Add final touches

This commit is contained in:
Schmelczer András 2020-01-10 20:10:59 +01:00
parent b1fd2f372f
commit 0429ea7f72
64 changed files with 576 additions and 444 deletions

View file

@ -2,6 +2,8 @@
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="CssInvalidAtRule" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidFunction" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="JSBitwiseOperatorUsage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SassScssResolvedByNameOnly" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
</profile>
</component>

101
.idea/workspace.xml generated
View file

@ -2,13 +2,68 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="8edc47ab-1265-4111-9771-536b24cc9310" name="Default Changelist" comment="">
<change afterPath="$PROJECT_DIR$/src/framework/helper/animations/animations.scss" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/framework/index.scss" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/framework/framework.scss" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/framework/styles/dark-mode/dark-mode.scss" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/framework/styles/index.scss" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/framework/styles/wrapper.scss" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/static/media/my-notes.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/style/_id.scss" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/style/configured-responsive.scss" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/style/include.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/helper/animations.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/helper/animations/animations.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/custom.d.ts" beforeDir="false" afterPath="$PROJECT_DIR$/custom.d.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/container-page.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/container-page.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/event-broadcaster.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/events/event-broadcaster.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/helper/animations/animations.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/styles/animations/animations.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/helper/animations/animations.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/styles/animations/animations.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/helper/create-element.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/helper/create-element.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/helper/dark-mode.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/styles/dark-mode/dark-mode.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/index.scss" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/page-element.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/page-element.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/page-event.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/events/page-event.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/primitives/implementations/anchor.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/primitives/implementations/anchor.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/primitives/implementations/image.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/primitives/implementations/image.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/primitives/implementations/text.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/primitives/implementations/text.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/primitives/implementations/video.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/primitives/implementations/video.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/primitives/primitive.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/primitives/primitive.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/framework/primitives/primitives.scss" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/model/misc.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/model/misc.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/model/portfolio.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/model/portfolio.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/about/about.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/about/about.html.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/about/about.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/about/about.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/about/about.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/about/about.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/background/background.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/background/blob.html.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/background/background.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/background/background.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/background/background.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/background/background.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/background/blob.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/background/blob.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/content/content.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/content/content.html.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/content/content.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/content/content.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/footer/footer.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/footer/footer.html.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/footer/footer.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/footer/footer.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/image-viewer/image-viewer.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/image-viewer/image-viewer.html.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/image-viewer/image-viewer.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/image-viewer/image-viewer.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/image-viewer/image-viewer.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/image-viewer/image-viewer.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/index.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/theme-switcher/theme-switcher.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/theme-switcher/theme-switcher.html.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/theme-switcher/theme-switcher.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/theme-switcher/theme-switcher.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/theme-switcher/theme-switcher.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/theme-switcher/theme-switcher.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.html.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline.html.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/portfolio.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/portfolio.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/static/media/my-notes.jpg" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/a.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/a.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/fonts.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/fonts.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/mixins.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/mixins.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/vars.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/vars.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/styles.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/styles.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/webpack.config.js" beforeDir="false" afterPath="$PROJECT_DIR$/webpack.config.js" afterDir="false" />
</list>
@ -29,6 +84,9 @@
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="HighlightingSettingsPerFile">
<setting file="file://$PROJECT_DIR$/src/style/configured-responsive.scss" root0="FORCE_HIGHLIGHTING" />
</component>
<component name="ProjectId" id="1UhDrRKewMzhTrQJ4npWjp729uJ" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
<ConfirmationsSetting value="2" id="Add" />
@ -62,11 +120,11 @@
<recent name="$PROJECT_DIR$" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/src/framework/events" />
<recent name="$PROJECT_DIR$/src/framework/model" />
<recent name="$PROJECT_DIR$/src/framework/styles/dark-mode" />
<recent name="$PROJECT_DIR$/src/framework/styles" />
<recent name="$PROJECT_DIR$/src/framework/helper/animations" />
<recent name="$PROJECT_DIR$/src/framework/helper" />
<recent name="$PROJECT_DIR$/src/framework/primitives/implementations" />
<recent name="C:\Projects\portfolio\CompiledCV\src\static\fonts" />
<recent name="C:\Projects\portfolio\CompiledCV\src\static\cv" />
</key>
</component>
<component name="ServiceViewManager">
@ -124,7 +182,8 @@
<workItem from="1578392333248" duration="21735000" />
<workItem from="1578472848376" duration="13670000" />
<workItem from="1578556192921" duration="3098000" />
<workItem from="1578559306201" duration="30000" />
<workItem from="1578559306201" duration="8231000" />
<workItem from="1578641947739" duration="23098000" />
</task>
<servers />
</component>
@ -147,4 +206,30 @@
<component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
</component>
<component name="WindowStateProjectService">
<state x="1515" y="215" width="800" height="684" key="#Inspections" timestamp="1578563668907">
<screen x="0" y="27" width="2560" height="1053" />
</state>
<state x="1515" y="215" width="800" height="684" key="#Inspections/0.27.2560.1053@0.27.2560.1053" timestamp="1578563668907" />
<state x="1648" y="359" width="545" height="410" key="#com.intellij.fileTypes.FileTypeChooser" timestamp="1578643626511">
<screen x="0" y="27" width="2560" height="1053" />
</state>
<state x="1648" y="359" width="545" height="410" key="#com.intellij.fileTypes.FileTypeChooser/0.27.2560.1053@0.27.2560.1053" timestamp="1578643626511" />
<state x="1653" y="303" width="524" height="508" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog" timestamp="1578646728957">
<screen x="0" y="27" width="2560" height="1053" />
</state>
<state x="1653" y="303" width="524" height="508" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog/0.27.2560.1053@0.27.2560.1053" timestamp="1578646728957" />
<state x="1664" y="411" width="502" height="292" key="ANALYSIS_DLG_com.intellij.analysis.BaseAnalysisAction$1" timestamp="1578563647005">
<screen x="0" y="27" width="2560" height="1053" />
</state>
<state x="1664" y="411" width="502" height="292" key="ANALYSIS_DLG_com.intellij.analysis.BaseAnalysisAction$1/0.27.2560.1053@0.27.2560.1053" timestamp="1578563647005" />
<state x="1072" y="473" width="415" height="167" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2" timestamp="1578659707248">
<screen x="0" y="27" width="2560" height="1053" />
</state>
<state x="1072" y="473" width="415" height="167" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2/0.27.2560.1053@0.27.2560.1053" timestamp="1578659707248" />
<state x="1603" y="289" width="774" height="677" key="find.popup" timestamp="1578682206106">
<screen x="0" y="27" width="2560" height="1053" />
</state>
<state x="1603" y="289" width="774" height="677" key="find.popup/0.27.2560.1053@0.27.2560.1053" timestamp="1578682206106" />
</component>
</project>

View file

@ -6,7 +6,7 @@ An easily configurable portfolio.
## Configuration
- The actual content is in [portfolio.ts](src/portfolio.ts).
- The assets referenced by this file should be located in [src/static](src/static).
- The assets referenced by that file should be located in [src/static](src/static).
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/hu/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/2.5/hu/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/hu/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Hungary License</a>.

32
custom.d.ts vendored
View file

@ -1,47 +1,47 @@
declare module "*.svg" {
import { url } from "src/model/misc";
declare module '*.svg' {
import { url } from 'src/framework/model/misc';
const content: url;
export default content;
}
declare module "*.png" {
import { ResponsiveImage } from "src/model/misc";
declare module '*.png' {
import { ResponsiveImage } from 'src/framework/model/misc';
const content: ResponsiveImage;
export default content;
}
declare module "*.jpg" {
import { ResponsiveImage } from "src/model/misc";
declare module '*.jpg' {
import { ResponsiveImage } from 'src/framework/model/misc';
const content: ResponsiveImage;
export default content;
}
declare module "*.jpeg" {
import { ResponsiveImage } from "src/model/misc";
declare module '*.jpeg' {
import { ResponsiveImage } from 'src/framework/model/misc';
const content: ResponsiveImage;
export default content;
}
declare module "*.gif" {
import { url } from "src/model/misc";
declare module '*.gif' {
import { url } from 'src/framework/model/misc';
const content: url;
export default content;
}
declare module "*.mp4" {
import { url } from "src/model/misc";
declare module '*.mp4' {
import { url } from 'src/framework/model/misc';
const content: url;
export default content;
}
declare module "*.webm" {
import { url } from "src/model/misc";
declare module '*.webm' {
import { url } from 'src/framework/model/misc';
const content: url;
export default content;
}
declare module "*.pdf" {
import { url } from "src/model/misc";
declare module '*.pdf' {
import { url } from 'src/framework/model/misc';
const content: url;
export default content;
}

View file

@ -55,9 +55,7 @@
"typescript": "^3.7.3",
"webpack": "^4.41.4",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.1"
},
"dependencies": {
"sass": "latest"
"webpack-dev-server": "^3.10.1",
"cssnano": "latest"
}
}

View file

@ -1,5 +1,5 @@
import { PageElement } from './page-element';
import { PageEventType } from './page-event';
import { PageEventType } from './events/page-event';
export class ContainerPage extends PageElement {
public constructor(rootElement: HTMLElement, children: Array<PageElement>) {

View file

@ -0,0 +1 @@
@forward "styles/index";

View file

@ -1,4 +1,4 @@
import { html } from '../../model/misc';
import { html } from '../model/misc';
export const createElement = (from: html): HTMLElement => {
// won't work for all elements, eg.: <td>

View file

@ -1,2 +0,0 @@
@import 'primitives/primitives';
@import 'helper/animations/animations';

View file

@ -1,5 +1,5 @@
import { PageEvent, PageEventType } from './page-event';
import { EventBroadcaster } from './event-broadcaster';
import { PageEvent, PageEventType } from './events/page-event';
import { EventBroadcaster } from './events/event-broadcaster';
export abstract class PageElement implements EventBroadcaster {
protected eventBroadcaster: EventBroadcaster;

View file

@ -1,5 +1,5 @@
import { Primitive } from '../primitive';
import { html, url } from '../../../model/misc';
import { html, url } from '../../model/misc';
export class Anchor implements Primitive {
public constructor(
@ -8,10 +8,12 @@ export class Anchor implements Primitive {
) {}
public toHTML(): html {
return `<a class="primitive-anchor"
href="${this.href}"
rel="noreferrer"
target="_blank"
>${this.text}</a>`;
return `
<a class="primitive-anchor"
href="${this.href}"
rel="noreferrer"
target="_blank"
>${this.text}</a>
`;
}
}

View file

@ -1,5 +1,5 @@
import { Primitive } from '../primitive';
import { html, ResponsiveImage } from '../../../model/misc';
import { html, ResponsiveImage } from '../../model/misc';
import { last } from '../../helper/last';
export class Image implements Primitive {
@ -11,7 +11,7 @@ export class Image implements Primitive {
public toHTML(disableInnerShadow = false): html {
return `
${!disableInnerShadow ? `<div class="figure-container">` : ''}
<img
<img tabindex="0"
srcset="${this.image.srcSet}"
src="${last(this.image.images)?.path}"
alt="${this.alt}"

View file

@ -1,5 +1,5 @@
import { Primitive } from '../primitive';
import { html } from '../../../model/misc';
import { html } from '../../model/misc';
export class Text implements Primitive {
public constructor(private readonly text: string) {}

View file

@ -1,5 +1,5 @@
import { Primitive } from '../primitive';
import { url } from '../../../model/misc';
import { url } from '../../model/misc';
export class Video implements Primitive {
public constructor(
@ -11,7 +11,9 @@ export class Video implements Primitive {
public toHTML(disableInnerShadow = false): string {
return `
${!disableInnerShadow ? `<div class="figure-container">` : ''}
<video ${this.options} poster="${this.poster}">
<video ${this.options} ${
this.poster ? `poster="${this.poster}` : ''
}" >
<source src="${this.webm}" type="video/webm"/>
<source src="${this.mp4}" type="video/mp4"/>
</video>

View file

@ -1,6 +1,4 @@
import { html } from '../../model/misc';
import './primitives.scss';
import { html } from '../model/misc';
export interface Primitive {
toHTML(): html;

View file

@ -1,27 +0,0 @@
@import '../../style/vars';
@import '../../style/mixins';
@include responsive() using ($vars) {
.figure-container {
font-size: 0;
box-shadow: inset map_get($vars, $shadow1), inset map_get($vars, $shadow2);
pointer-events: none;
cursor: pointer;
* {
pointer-events: all;
position: relative;
z-index: -2;
}
}
.primitive-text,
.primitive-anchor,
.figure-container {
margin-top: map_get($vars, $line-height);
}
.primitive-text {
text-align: left;
}
}

View file

@ -0,0 +1,5 @@
@mixin in-dark-mode() {
&[theme='dark'] {
@content;
}
}

View file

@ -0,0 +1,3 @@
@forward 'animations/animations';
@forward 'dark-mode/dark-mode';
@forward 'wrapper';

View file

@ -0,0 +1,38 @@
@use 'dark-mode/dark-mode' as *;
$breakpoint-width: 925px !default;
$small-screen-light-theme-variables: () !default;
$small-screen-dark-theme-variables: () !default;
$large-screen-light-theme-variables: () !default;
$large-screen-dark-theme-variables: () !default;
@mixin on-small-screen() {
@media (max-width: $breakpoint-width) {
@content;
}
}
@mixin on-large-screen() {
@media (min-width: $breakpoint-width) {
@content;
}
}
@mixin responsive() {
html {
@include on-small-screen {
@content ($small-screen-light-theme-variables);
@include in-dark-mode {
@content ($small-screen-dark-theme-variables);
}
}
}
@include on-large-screen {
html {
@content ($large-screen-light-theme-variables);
@include in-dark-mode {
@content ($large-screen-dark-theme-variables);
}
}
}
}

View file

@ -14,7 +14,6 @@
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover" />
<meta name="theme-color" content="#b7455e" />
<title>Portfolio - András Schmelczer</title>
</head>
<body>

View file

@ -1,9 +1,9 @@
import "./static/no-change/favicon.ico";
import "./static/no-change/og-image.jpg";
import { create } from './page/index';
import { portfolio } from './portfolio';
import "./styles.scss";
import './static/no-change/favicon.ico';
import './static/no-change/og-image.jpg';
import { create } from "./page/index";
import { portfolio } from "./portfolio";
import './styles.scss';
create(portfolio);

View file

@ -1,4 +1,4 @@
import { url } from './misc';
import { url } from '../framework/model/misc';
import { Primitive } from '../framework/primitives/primitive';
import { Image } from '../framework/primitives/implementations/image';
import { Anchor } from '../framework/primitives/implementations/anchor';

View file

@ -1,5 +1,5 @@
import { Header } from '../../model/portfolio';
import { html } from '../../model/misc';
import { html } from '../../framework/model/misc';
import './about.scss';

View file

@ -1,23 +1,16 @@
@import '../../style/mixins';
@import '../../style/vars';
@use '../../style/include' as *;
@include responsive() using ($vars) {
#about {
section#about {
@include card-base($vars);
background-color: map_get($vars, $important-card-color);
* {
color: map_get($vars, $important-card-text-color);
}
background-color: map_get($vars, $accent-color);
font-size: 0;
$img-size: 125px;
h1,
img,
.placeholder,
& {
@include title-font();
.placeholder {
@include title-font($vars);
}
img {
@ -26,19 +19,18 @@
}
p {
@include main-font();
@include main-font($vars);
text-align: justify;
margin-top: map_get($vars, $small-margin);
}
h1 {
hyphens: none;
}
@include on-small-screen {
h1 {
margin-top: map_get($vars, $small-margin);
}
p,
h1 {
color: map_get($vars, $very-light-text-color);
margin-top: map_get($vars, $small-margin);
}
@include on-large-screen {
@ -69,6 +61,7 @@
h1 {
text-align: left;
margin-top: 0;
}
}
}

View file

@ -1,6 +1,5 @@
import { PageContent } from '../content/content';
import { Header } from '../../model/portfolio';
import { PageElement } from '../../framework/page-element';
import { generate } from './about.html';
import { createElement } from '../../framework/helper/create-element';

View file

@ -1,9 +1,7 @@
@import '../../style/vars';
@import '../../style/mixins';
@use '../../style/include' as *;
@include responsive() using ($vars) {
div.background-element {
position: -webkit-sticky;
position: absolute;
left: 0;
top: 0;
@ -24,9 +22,9 @@
}
}
transition: transform map_get($vars, $long-transition-time),
opacity map_get($vars, $long-transition-time),
background-color map_get($vars, $long-transition-time);
transition: transform map_get($vars, $transition-time),
opacity map_get($vars, $transition-time),
background-color map_get($vars, $transition-time);
will-change: transform, opacity;
animation: fade-in 1s linear;

View file

@ -1,5 +1,5 @@
import { PageElement } from '../../framework/page-element';
import { PageEvent, PageEventType } from '../../framework/page-event';
import { PageEvent, PageEventType } from '../../framework/events/page-event';
import { Blob } from './blob';
import { Random } from '../../framework/helper/random';
import { getHeight } from '../../framework/helper/get-height';
@ -15,13 +15,17 @@ export class PageBackground extends PageElement {
}
protected handleEvent(event: PageEvent, parent: PageElement) {
if (event.type === PageEventType.onLoad) {
this.bindListeners(parent);
} else if (event.type === PageEventType.onBodyDimensionsChanged) {
this.resize(parent, event.data?.deltaHeight);
} else if (event.type === PageEventType.pageThemeChanged) {
Blob.changeTheme(event.data);
this.blobs.forEach(b => b.decideColor());
switch (event.type) {
case PageEventType.onLoad:
this.bindListeners(parent);
break;
case PageEventType.onBodyDimensionsChanged:
this.resize(parent, event.data?.deltaHeight);
break;
case PageEventType.pageThemeChanged:
Blob.changeTheme(event.data);
this.blobs.forEach(b => b.decideColor());
break;
}
}

View file

@ -1,4 +1,4 @@
import { html } from '../../model/misc';
import { html } from '../../framework/model/misc';
import './background.scss';
export const generate = (): html => `

View file

@ -1,14 +1,15 @@
import { mixColors } from '../../framework/helper/mix-colors';
import { createElement } from '../../framework/helper/create-element';
import { Random } from '../../framework/helper/random';
import { generate } from './background.html';
import { generate } from './blob.html';
export class Blob {
private static readonly creatorRandom = new Random(44);
private static colorPickerRandom = new Random(132);
private static readonly darkColors = ['#2c477a'];
private static readonly lightColors = ['#fff9e0', '#ffd6d6'];
private static readonly darkColors = ['#2C477A'];
private static colorPickerRandom = new Random(132);
private static isDarkThemed = false;
private static zMin: number;
private static zMax: number;
private static perspective: number;

View file

@ -1,5 +1,5 @@
import { Content } from '../../model/portfolio';
import { html } from '../../model/misc';
import { html } from '../../framework/model/misc';
import './content.scss';

View file

@ -1,8 +1,11 @@
@import '../../style/vars';
@import '../../style/mixins';
@use '../../style/include' as *;
@include responsive() using ($vars) {
.content {
margin-top: map_get($vars, $small-margin);
:first-child {
margin-top: 0;
}
}
}

View file

@ -1,5 +1,5 @@
import { Footer } from '../../model/portfolio';
import { html } from '../../model/misc';
import { html } from '../../framework/model/misc';
import './footer.scss';

View file

@ -1,21 +1,20 @@
@import '../../style/mixins';
@import '../../style/vars';
@use '../../style/include' as *;
@include responsive() using ($vars) {
footer#page-footer {
text-align: center;
margin: map_get($vars, $large-margin) auto 0 auto;
margin-top: map_get($vars, $large-margin);
width: 100%;
h2 {
@include title-font();
@include title-font($vars);
}
ul {
margin-top: map_get($vars, $normal-margin);
list-style: none;
display: inline-block;
margin-top: map_get($vars, $normal-margin);
text-align: left;
li {
@ -29,10 +28,11 @@
img,
svg {
@include max-square(map_get($vars, $icon-size));
margin-right: map_get($vars, $small-margin);
* {
fill: map_get($vars, $normal-text-color);
}
margin-right: map_get($vars, $small-margin);
}
a {
@ -44,13 +44,17 @@
aside.other {
@include center-children();
flex-direction: column;
margin: map_get($vars, $large-margin) auto map_get($vars, $line-height)
auto;
margin: map_get($vars, $large-margin) auto 0 auto;
padding-bottom: map_get($vars, $line-height);
width: map_get($vars, $body-width);
h6 {
@include special-text-font($vars);
display: inline;
&,
* {
@include special-text-font($vars);
color: map_get($vars, $normal-text-color);
}
opacity: 0.75;
}
}

View file

@ -1,4 +1,4 @@
import { html } from '../../model/misc';
import { html } from '../../framework/model/misc';
import cancel from '../../static/icons/cancel.svg';
import './image-viewer.scss';
@ -6,6 +6,6 @@ import './image-viewer.scss';
export const generate = (): html => `
<section id="image-viewer">
<div id="container"></div>
<img id="cancel" src="${cancel}" alt="cancel"/>
<img tabindex="0" id="cancel" src="${cancel}" alt="cancel"/>
</section>
`;

View file

@ -1,8 +1,7 @@
@import '../../style/vars';
@import '../../style/mixins';
@use '../../style/include' as *;
@include responsive() using ($vars) {
#image-viewer {
section#image-viewer {
@include center-children();
display: none;
position: fixed;

View file

@ -1,7 +1,7 @@
import { PageElement } from '../../framework/page-element';
import { generate } from './image-viewer.html';
import { PageEvent, PageEventType } from '../../framework/page-event';
import { PageEvent, PageEventType } from '../../framework/events/page-event';
import { createElement } from '../../framework/helper/create-element';
export class PageImageViewer extends PageElement {
@ -11,24 +11,19 @@ export class PageImageViewer extends PageElement {
}
protected handleEvent(event: PageEvent, parent: PageElement) {
if (event.type !== PageEventType.onLoad) {
return;
}
if (event.type === PageEventType.onLoad) {
document.body.addEventListener('keydown', this.handleKeydown.bind(this));
document.body.addEventListener('keydown', this.handleKeydown.bind(this));
const media = Array.prototype.slice.call(
parent.element.querySelectorAll('img, video')
);
media
.filter(
(e: HTMLElement) =>
e.parentElement !== this.element && !e.classList.contains('no-open')
)
.forEach(
(e: HTMLImageElement) => (e.onclick = this.handleClick.bind(this))
const media = Array.prototype.slice.call(
parent.element.querySelectorAll('img')
);
media
.filter((e: HTMLElement) => e.parentElement !== this.element)
.forEach(
(e: HTMLImageElement) => (e.onclick = this.handleClick.bind(this))
);
}
}
private handleClick(event: Event) {

View file

@ -19,4 +19,20 @@ export const create = ({ header, timeline, footer }: Portfolio) => {
new PageBackground(pageHeader, pageFooter),
]),
]).setAsMain();
addSupportForTabNavigation();
removeUnnecessaryOutlines();
};
const addSupportForTabNavigation = () =>
(document.onkeydown = e => {
if (e.key === ' ') {
(document.activeElement as HTMLElement)?.click();
e.preventDefault();
}
});
const removeUnnecessaryOutlines = () =>
(document.onclick = e => {
(e.target as HTMLElement)?.blur();
});

View file

@ -1,7 +1,7 @@
import { html } from '../../model/misc';
import { html } from '../../framework/model/misc';
import './theme-switcher.scss';
export const generate = (): html => `
<input id="theme-switcher" type="checkbox" name="switch-theme"/>
<input id="theme-switcher" aria-label="color-theme-switch" type="checkbox" name="switch-theme"/>
`;

View file

@ -1,5 +1,4 @@
@import '../../style/mixins';
@import '../../style/vars';
@use '../../style/include' as *;
@include responsive using($vars) {
input[type='checkbox']#theme-switcher {
@ -14,11 +13,12 @@
margin-top: map_get($vars, $normal-margin);
}
&::-ms-check {
display: none;
}
background-color: map_get($vars, $accent-color);
z-index: 10;
cursor: pointer;
-webkit-appearance: none;
-moz-appearance: none;
@ -33,10 +33,12 @@
inset 0 0 1px rgba(0, 0, 0, 0.4);
&:before {
// moon + sun
@include square($icon-size);
}
&:after {
// sun blocking moon
@include square($icon-size * 0.8);
}
@ -50,8 +52,8 @@
top: 50%;
transform: translateY(-50%);
transition: transform map_get($vars, $long-transition-time),
background-color map_get($vars, $long-transition-time);
transition: transform map_get($vars, $transition-time),
background-color map_get($vars, $transition-time);
}
&:not(:checked) {
@ -59,16 +61,16 @@
transform: translateY(-50%) translateX(3 * $margin + $icon-size);
animation: shine 3s linear alternate infinite;
background-color: map_get($vars, $theme-switcher-foreground);
background-color: map_get($vars, $sun-color);
@keyframes shine {
from {
filter: brightness(1.01);
box-shadow: 0 0 4px 2px map_get($vars, $theme-switcher-foreground);
box-shadow: 0 0 4px 2px map_get($vars, $sun-color);
}
to {
filter: brightness(1.1);
box-shadow: 0 0 15px 2px map_get($vars, $theme-switcher-foreground);
box-shadow: 0 0 15px 2px map_get($vars, $sun-color);
}
}
}
@ -90,9 +92,5 @@
transform: translateY(-50%) translateX($margin + $icon-size * 0.33);
}
}
&:focus {
outline: 0;
}
}
}

View file

@ -5,13 +5,13 @@ import {
isSystemLevelDarkModeEnabled,
turnOnDarkMode,
turnOnLightMode,
} from '../../framework/helper/dark-mode';
import { PageEvent, PageEventType } from '../../framework/page-event';
import { EventBroadcaster } from '../../framework/event-broadcaster';
} from '../../framework/styles/dark-mode/dark-mode';
import { PageEvent, PageEventType } from '../../framework/events/page-event';
import { EventBroadcaster } from '../../framework/events/event-broadcaster';
import {
turnOffAnimations,
turnOnAnimations,
} from '../../framework/helper/animations/animations';
} from '../../framework/styles/animations/animations';
export class PageThemeSwitcher extends PageElement {
private static readonly LOCAL_STORAGE_KEY = 'dark-mode';
@ -62,9 +62,12 @@ export class PageThemeSwitcher extends PageElement {
}
private static loadFromLocalStorage(): boolean | null {
return JSON.parse(
window.localStorage?.getItem(PageThemeSwitcher.LOCAL_STORAGE_KEY) ||
'null'
);
try {
return JSON.parse(
window.localStorage?.getItem(PageThemeSwitcher.LOCAL_STORAGE_KEY)
);
} catch {
return null;
}
}
}

View file

@ -1,5 +1,5 @@
import { TimelineElement } from '../../../model/portfolio';
import { html } from '../../../model/misc';
import { html } from '../../../framework/model/misc';
import './timeline-element.scss';
@ -22,8 +22,8 @@ export const generate = (
? `
<div class="more"></div>
<div class="buttons">
<a class="show-more">${showMore}</a>
<a class="show-less">${showLess}</a>
<a tabindex="0" class="show-more">${showMore}</a>
<a tabindex="0" class="show-less">${showLess}</a>
</div>
`
: ''

View file

@ -1,5 +1,4 @@
@import '../../../style/mixins';
@import '../../../style/vars';
@use '../../../style/include' as *;
@mixin q-dependent-line-container($vars, $q) {
.line {
@ -18,7 +17,7 @@
}
@include responsive() using ($vars) {
.timeline-element {
section.timeline-element {
display: flex;
width: map_get($vars, $body-width);
margin: auto;
@ -32,9 +31,13 @@
border-left: map_get($vars, $line-width) solid
map_get($vars, $accent-color);
&:before {
&:before,
&:after {
content: '';
position: absolute;
}
&:before {
left: 0;
bottom: 0;
border-left: map_get($vars, $line-width) solid
@ -42,12 +45,10 @@
}
&:after {
content: '';
@include square(map_get($vars, $icon-size));
border-radius: 1000px;
border: map_get($vars, $line-width) solid
map_get($vars, $accent-color);
position: absolute;
left: -1 * map_get($vars, $icon-size) / 2 +
map_get($vars, $line-width) / 2;
}
@ -88,18 +89,19 @@
.card {
@include card-base($vars);
border-radius: map_get($vars, $border-radius);
background-color: map_get($vars, $card-color);
overflow: hidden;
& > *:not(:first-child) {
margin-top: map_get($vars, $line-height);
}
.content {
margin-top: 0;
}
h2 {
@include sub-title-font();
@include sub-title-font($vars);
}
& > p {
@ -110,16 +112,16 @@
.more {
overflow: hidden;
height: 0;
margin-top: 0;
transition: height map_get($vars, $long-transition-time);
transition: height map_get($vars, $transition-time);
}
.buttons {
position: relative;
margin-top: map_get($vars, $small-margin);
margin-top: map_get($vars, $line-height);
* {
transition: opacity map_get($vars, $long-transition-time);
.show-more,
.show-less {
transition: opacity map_get($vars, $transition-time);
}
.show-more {
@ -127,9 +129,9 @@
}
.show-less {
@include absolute-center();
opacity: 0;
visibility: hidden;
@include absolute-center();
}
}
}

View file

@ -2,11 +2,11 @@ import { TimelineElement } from '../../../model/portfolio';
import { PageContent } from '../../content/content';
import { PageElement } from '../../../framework/page-element';
import { generate } from './timeline-element.html';
import { PageEventType } from '../../../framework/page-event';
import { PageEventType } from '../../../framework/events/page-event';
import { createElement } from '../../../framework/helper/create-element';
export class PageTimelineElement extends PageElement {
private isOpen;
private isOpen: boolean;
private more: HTMLElement;
public constructor(
@ -56,7 +56,7 @@ export class PageTimelineElement extends PageElement {
this.eventBroadcaster?.broadcastEvent({
type: PageEventType.onBodyDimensionsChanged,
}),
350
250
);
}
@ -64,7 +64,7 @@ export class PageTimelineElement extends PageElement {
element.style.opacity = '0';
setTimeout(() => {
element.style.visibility = 'hidden';
}, 350);
}, 250);
}
private static show(element: HTMLElement) {

View file

@ -1,5 +1,5 @@
import { html } from "../../model/misc";
import "./timeline.scss";
import { html } from '../../framework/model/misc';
import './timeline.scss';
export const generate = (): html => `
<main id="timeline"></main>

View file

@ -1,8 +1,7 @@
@import '../../style/vars';
@import '../../style/mixins';
@use '../../style/include' as *;
@include responsive() using ($vars) {
#timeline {
main#timeline {
@include on-large-screen {
// workaround for IE
& > :first-child {

View file

@ -1,5 +1,4 @@
import { Timeline } from '../../model/portfolio';
import { PageElement } from '../../framework/page-element';
import { PageTimelineElement } from './timeline-element/timeline-element';
import { generate } from './timeline.html';
import { createElement } from '../../framework/helper/create-element';

View file

@ -5,10 +5,9 @@ import { Video } from './framework/primitives/implementations/video';
import { Anchor } from './framework/primitives/implementations/anchor';
import me from './static/media/me.jpg';
import forexGIF from './static/media/forex.gif';
import forexMP4 from './static/media/forex.mp4';
import forexWEBM from './static/media/forex.webm';
import myNotes from './static/media/my-notes.jpg';
import myNotes from './static/media/my-notes.png';
import processSimulator from './static/media/process-simulator.jpg';
import processSimulatorInput from './static/media/process-simulator-input.jpg';
import citySimulation from './static/media/simulation.jpg';
@ -19,6 +18,7 @@ import led from './static/media/led.jpg';
import cv from './static/cv/andras_schmelczer_cv_2020_01.pdf';
import ledMP4 from './static/media/led.mp4';
import ledWEBM from './static/media/led.webm';
import { last } from './framework/helper/last';
export const portfolio: Portfolio = {
header: {
@ -44,10 +44,10 @@ export const portfolio: Portfolio = {
title: `Predicting foreign exchange rates`,
date: `2019 Autumn`,
figure: new Video(
forexGIF,
null,
forexMP4,
forexWEBM,
`autoplay loop muted playsinline`
`autoplay loop muted playsinline controls`
),
description: new Text(
`From the animation we can see that my algorithm does a somewhat acceptable job at
@ -74,13 +74,13 @@ export const portfolio: Portfolio = {
`A minimalist note organizer and editor powered by Markwon.`
),
more: [
new Text(
`A basic android app for creating and filtering notes written in markdown.`
),
new Anchor(
`https://github.com/schmelczerandras/my-notes`,
`MyNotes on GitHub`
),
new Text(
`A basic android app for creating and filtering notes written in markdown.`
),
new Text(
`It was my homework for BME's Android and web development course.
It was also my first experience with Android development.`
@ -211,7 +211,12 @@ export const portfolio: Portfolio = {
{
date: `2016 spring`,
title: `Lights synchronised to music`,
figure: new Video(led.src, ledMP4, ledWEBM, `controls`),
figure: new Video(
last(led.images).path,
ledMP4,
ledWEBM,
`controls playsinline preload="none"`
),
description: new Text(
`A full stack application with a built-in
music player which music controls the color of some RGB LED strips.`
@ -233,15 +238,15 @@ export const portfolio: Portfolio = {
footer: {
title: `Learn more`,
curiumVitaes: [
{ name: `Curriculum vitae (en)`, url: cv },
{ name: `Önéletrajz (hu)`, url: cv },
{ name: `Curriculum vitae`, url: cv },
/*{ name: `Önéletrajz (hu)`, url: cv },*/
],
email: `andras@schmelczer.dev`,
lastEditText: `Last modified on `,
lastEdit: new Date(2020, 0, 6), // months are 0 indexed
lastEdit: new Date(2020, 0, 10), // months are 0 indexed
gitHub: new Anchor(
`https://github.com/schmelczerandras/timeline`,
`Find this page on GitHub.`
`Find this on GitHub`
),
},
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 MiB

6
src/style/_id.scss Normal file
View file

@ -0,0 +1,6 @@
$_id_value: 0;
@function id() {
$_id_value: $_id_value + 1 !global;
@return $_id_value;
}

View file

@ -1,48 +1,48 @@
@import 'vars';
@import 'mixins';
@use 'sass:color';
@use 'include' as i;
@include responsive() using ($vars) {
@include i.responsive() using ($vars) {
a {
@include special-text-font($vars);
$border-shift: 10px;
$line-width: 2px;
@include i.special-text-font($vars);
text-decoration: none;
position: relative;
cursor: pointer;
position: relative;
display: inline-block;
overflow: hidden;
$border-shift: 10px;
transition: transform map_get($vars, $long-transition-time);
&:before {
content: '';
display: block;
position: absolute;
width: 100%;
height: map_get($vars, $line-width);
bottom: 0;
z-index: 1;
background: linear-gradient(
90deg,
map_get($vars, $card-color) 0,
transparentize(map_get($vars, $card-color), 1) 4px,
transparentize(map_get($vars, $card-color), 1) calc(100% - 4px),
map_get($vars, $card-color) 100%
);
}
padding-bottom: $line-width;
&:before,
&:after {
content: '';
display: block;
position: absolute;
bottom: 0;
}
&:before {
width: calc(100% + #{$border-shift});
z-index: 0;
border-bottom: map_get($vars, $line-width) dashed
map_get($vars, $accent-color);
transition: transform map_get($vars, $long-transition-time);
border-bottom: $line-width dashed map_get($vars, i.$accent-color);
transition: transform map_get($vars, i.$transition-time);
}
&:after {
width: 100%;
height: $line-width;
background: linear-gradient(
90deg,
map_get($vars, i.$card-color) 0,
color.adjust(map_get($vars, i.$card-color), $alpha: -1) 4px,
color.adjust(map_get($vars, i.$card-color), $alpha: -1) calc(100% - 4px),
map_get($vars, i.$card-color) 100%
);
}
&:hover {
&:after {
&:before {
transform: translateX(-$border-shift);
}
}

View file

@ -0,0 +1,7 @@
@use 'vars';
@forward "../framework/framework" with (
$small-screen-light-theme-variables: vars.$small-screen-light-theme-variables,
$small-screen-dark-theme-variables: vars.$small-screen-dark-theme-variables,
$large-screen-light-theme-variables: vars.$large-screen-light-theme-variables,
$large-screen-dark-theme-variables: vars.$large-screen-dark-theme-variables,
);

View file

@ -1,6 +1,4 @@
// https://google-webfonts-helper.herokuapp.com/fonts/montserrat?subsets=latin
// add font-display: swap;
/*
/* lato-regular - latin */
@font-face {
font-family: 'Lato';

7
src/style/include.scss Normal file
View file

@ -0,0 +1,7 @@
@forward "configured-responsive";
@forward "mixins";
@forward "vars" hide
$small-screen-light-theme-variables,
$small-screen-dark-theme-variables,
$large-screen-light-theme-variables,
$large-screen-dark-theme-variables;

View file

@ -1,35 +1,5 @@
@import 'vars';
@mixin on-small-screen() {
@media (max-width: $breakpoint-width) {
@content;
}
}
@mixin on-large-screen() {
@media (min-width: $breakpoint-width) {
@content;
}
}
@mixin responsive() {
html {
@include on-small-screen {
@content (map_merge($small-screen-variables, $light-theme-variables));
&[theme='dark'] {
@content (map_merge($small-screen-variables, $dark-theme-variables));
}
}
}
@include on-large-screen {
html {
@content (map_merge($large-screen-variables, $light-theme-variables));
&[theme='dark'] {
@content (map_merge($large-screen-variables, $dark-theme-variables));
}
}
}
}
@use "configured-responsive";
@use "vars";
@mixin center-children() {
display: flex;
@ -46,17 +16,9 @@
@mixin card-base($vars) {
text-align: center;
padding: map_get($vars, $normal-margin);
box-shadow: map_get($vars, $shadow1), map_get($vars, $shadow2);
padding: map_get($vars, vars.$normal-margin);
box-shadow: map_get($vars, vars.$shadow);
z-index: 1;
@include on-large-screen {
transition: box-shadow map_get($vars, $long-transition-time),
background-color map_get($vars, $long-transition-time);
&:hover {
box-shadow: map_get($vars, $shadow3), map_get($vars, $shadow2);
}
}
}
@mixin square($size) {
@ -69,29 +31,32 @@
max-height: $size;
}
@mixin title-font() {
@mixin title-font($vars) {
font: 400 3.5rem 'Montserrat', serif;
font-style: normal;
color: map_get($vars, vars.$normal-text-color);
line-height: 1;
@include on-small-screen {
@include configured-responsive.on-small-screen {
font-size: 3rem;
line-height: 1.1;
}
}
@mixin sub-title-font() {
@mixin sub-title-font($vars) {
font: 400 2rem 'Montserrat', serif;
color: map_get($vars, vars.$normal-text-color);
font-style: normal;
}
@mixin main-font() {
@mixin main-font($vars) {
font: 400 1.25rem 'Lato', sans-serif;
color: map_get($vars, vars.$normal-text-color);
line-height: 1.6;
}
@mixin special-text-font($vars) {
font: 400 1.1rem 'Lato', sans-serif;
color: map_get($vars, $special-text-color);
color: map_get($vars, vars.$special-text-color);
font-style: italic;
}

View file

@ -1,115 +1,108 @@
@import 'fonts';
@use 'fonts';
@use "id" as *;
$_id_value: 0;
@function id() {
$_id_value: $_id_value + 1 !global;
@return $_id_value;
}
/* NAMES */
/* KEYS */
$background: id();
$normal-text-color: id();
$light-text-color: id();
$important-card-text-color: id();
$inverse-text-color: id();
$card-color: id();
$important-card-color: id();
$theme-switcher-background: id();
$theme-switcher-foreground: id();
$very-light-text-color: id();
$special-text-color: id();
$card-color: id();
$sun-color: id();
$accent-color: id();
$scrollbar-color: id();
$short-transition-time: id();
$long-transition-time: id();
$line-width: id();
$transition-time: id();
$border-radius: id();
$breakpoint-width: id();
$large-margin: id();
$normal-margin: id();
$small-margin: id();
$line-height: id();
$shadow1: id();
$shadow2: id();
$shadow3: id();
$line-width: id();
$body-width: id();
$small-margin: id();
$normal-margin: id();
$large-margin: id();
$icon-size: id();
$line-height: id();
$shadow: id();
$inset-shadow: id();
/**/
$breakpoint-width: 925px;
$universal-variables: (
$short-transition-time: 220ms,
$long-transition-time: 350ms,
$transition-time: 250ms,
$line-width: 3px,
$line-height: 18px,
$theme-switcher-foreground: #f7f78c,
$accent-color: #b7455e,
$important-card-color: #b7405a,
$shadow3: 0 0 15px 4px rgba(0, 0, 0, 0.1),
$sun-color: #f7f78c,
$very-light-text-color: #ffffff,
);
$large-screen-variables: map_merge(
(
$border-radius: 15px,
$large-margin: 70px,
$normal-margin: 45px,
$small-margin: 25px,
$shadow1: 0 0 10px 2px rgba(0, 0, 0, 0.075),
$shadow2: 0 0 1px rgba(0, 0, 0, 0.2),
$icon-size: 35px,
$body-width: 765px,
$large-screen-variables: (
$border-radius: 15px,
$large-margin: 70px,
$normal-margin: 45px,
$small-margin: 25px,
$shadow: (
0 0 10px 2px rgba(0, 0, 0, 0.075),
0 0 1px rgba(0, 0, 0, 0.2),
),
$universal-variables
$inset-shadow: (
inset 0 0 10px 2px rgba(0, 0, 0, 0.075),
inset 0 0 1px rgba(0, 0, 0, 0.2),
),
$icon-size: 35px,
$body-width: 765px,
);
$small-screen-variables: map_merge(
(
$border-radius: 10px,
$large-margin: 60px,
$normal-margin: 30px,
$small-margin: 15px,
$shadow1: 0 0 10px 2px rgba(0, 0, 0, 0.05),
$shadow2: 0 0 1px rgba(0, 0, 0, 0.125),
$icon-size: 25px,
$body-width: 90%,
$small-screen-variables: (
$border-radius: 10px,
$large-margin: 60px,
$normal-margin: 30px,
$small-margin: 15px,
$shadow: (
0 0 10px 2px rgba(0, 0, 0, 0.05),
0 0 1px rgba(0, 0, 0, 0.125),
),
$universal-variables
$inset-shadow: (
inset 0 0 10px 2px rgba(0, 0, 0, 0.05),
inset 0 0 1px rgba(0, 0, 0, 0.125),
),
$icon-size: 25px,
$body-width: 90%,
);
$light-theme-variables: map_merge(
(
$background: #ffffff,
$normal-text-color: #31343f,
$light-text-color: #7a7d8e,
$inverse-text-color: #ffffff,
$card-color: #ffffff,
$important-card-text-color: #ffffff,
$special-text-color: map_get($universal-variables, $accent-color),
$scrollbar-color: #ffd6d6,
),
$universal-variables
$light-theme-variables: (
$background: #ffffff,
$normal-text-color: #31343f,
$card-color: #ffffff,
$special-text-color: map_get($universal-variables, $accent-color),
);
$dark-theme-variables: map_merge(
(
$background: #242638,
$normal-text-color: #ffffff,
$light-text-color: #fff9e0,
$inverse-text-color: #242638,
$card-color: #263551,
$special-text-color: #ffffff,
$important-card-text-color: #fff9e0,
$scrollbar-color: #ffd6d6,
$shadow1: 0 0 10px 2px rgba(0, 0, 0, 0.175),
$shadow2: 0 0 1px rgba(0, 0, 0, 0.4),
$dark-theme-variables: (
$background: #242638,
$normal-text-color: #ffffff,
$card-color: #263551,
$special-text-color: #ffffff,
$shadow: (
0 0 10px 2px rgba(0, 0, 0, 0.175),
0 0 1px rgba(0, 0, 0, 0.4),
),
$inset-shadow: (
inset 0 0 10px 2px rgba(0, 0, 0, 0.175),
inset 0 0 1px rgba(0, 0, 0, 0.4),
),
$universal-variables
);
$small-screen-light-theme-variables: map_merge(
$universal-variables,
map_merge($small-screen-variables, $light-theme-variables)
);
$small-screen-dark-theme-variables: map_merge(
$universal-variables,
map_merge($small-screen-variables, $dark-theme-variables)
);
$large-screen-light-theme-variables: map_merge(
$universal-variables,
map_merge($large-screen-variables, $light-theme-variables)
);
$large-screen-dark-theme-variables: map_merge(
$universal-variables,
map_merge($large-screen-variables, $dark-theme-variables)
);

View file

@ -1,91 +1,120 @@
@import 'style/vars';
@import 'style/mixins';
@import 'style/a';
@import 'framework/index';
@use 'style/include' as *;
@use 'style/a';
@use 'framework/styles/index';
@include responsive() using ($vars) {
& {
background-color: map_get($vars, $background);
transition: background-color map_get($vars, $long-transition-time);
height: 100%;
background-color: map_get($vars, $background);
transition: background-color map_get($vars, $transition-time);
touch-action: manipulation;
@include on-small-screen {
font-size: 0.8em;
}
}
body {
@include main-font();
:focus {
outline: none;
//noinspection CssInvalidFunction
padding: env(safe-area-inset-top, 20px) env(safe-area-inset-right, 20px)
env(safe-area-inset-bottom, 20px) env(safe-area-inset-left, 20px);
&:not(:hover) {
outline: map_get($vars, $accent-color) solid 2px;
outline-offset: 4px;
}
}
height: 100%;
overflow: hidden;
::-moz-selection {
background-color: map_get($vars, $accent-color);
color: map_get($vars, $very-light-text-color);
}
::selection {
background-color: map_get($vars, $accent-color);
color: map_get($vars, $very-light-text-color);
}
*,
*::before,
*::after {
@include main-font($vars);
margin: 0;
padding: 0;
box-sizing: border-box;
color: map_get($vars, $normal-text-color);
transition: background-color map_get($vars, $long-transition-time),
color map_get($vars, $long-transition-time);
transition: background-color map_get($vars, $transition-time),
color map_get($vars, $transition-time);
hyphens: auto;
:focus {
/* border: 2px solid map_get($vars, $accent-color);
outline: 0;
border-radius: map_get($vars, $border-radius);*/
}
touch-action: manipulation;
}
img,
video {
video,
.figure-container {
width: 100%;
height: auto;
object-fit: contain;
}
::-moz-selection {
background: map_get($vars, $accent-color);
color: map_get($vars, $inverse-text-color);
}
::selection {
background: map_get($vars, $accent-color);
color: map_get($vars, $inverse-text-color);
}
.figure-container {
font-size: 0;
box-shadow: map_get($vars, $inset-shadow);
pointer-events: none;
cursor: pointer;
.main {
height: 100vh;
overflow-y: scroll;
overflow-x: hidden;
will-change: transform;
-webkit-overflow-scrolling: touch;
perspective: 5px;
perspective-origin: center center;
noscript {
@include square(100%);
@include center-children();
* {
pointer-events: all;
position: relative;
z-index: -2;
}
}
@include on-large-screen {
&::-webkit-scrollbar-track,
&::-webkit-scrollbar {
background-color: transparent;
width: 12px;
.primitive-text,
.primitive-anchor,
.figure-container {
margin-top: map_get($vars, $line-height);
}
.primitive-text {
text-align: left;
}
body {
height: 100%;
overflow: hidden;
//noinspection CssInvalidFunction
padding: env(safe-area-inset-top, 20px) env(safe-area-inset-right, 20px)
env(safe-area-inset-bottom, 20px) env(safe-area-inset-left, 20px);
.main {
height: 100vh; // to take mobile nav-bar into account
overflow-y: scroll;
overflow-x: hidden;
will-change: transform;
perspective: 5px;
perspective-origin: center center;
noscript {
@include square(100%);
@include center-children();
}
&::-webkit-scrollbar-thumb {
background-color: map_get($vars, $accent-color);
border-radius: map_get($vars, $border-radius);
@include on-large-screen {
&::-webkit-scrollbar-track,
&::-webkit-scrollbar {
background-color: transparent;
width: 12px;
}
&::-webkit-scrollbar-thumb {
background-color: map_get($vars, $accent-color);
border-radius: map_get($vars, $border-radius);
}
}
}
}

View file

@ -16,10 +16,15 @@ module.exports = {
},
devServer: {
host: '0.0.0.0',
// disableHostCheck: true,
disableHostCheck: true,
},
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
minimizer: [
new TerserJSPlugin({
sourceMap: !isProduction,
}),
new OptimizeCSSAssetsPlugin({}),
],
},
plugins: [
new CleanWebpackPlugin(),