diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 90bca187..a77d686a 100755 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -24,6 +24,7 @@ jobs: with: dotnet-version: '3.1.x' - run: | + bash ./install.sh -buildonly bash ./build.sh - name: Deploy 🚀 diff --git a/.gitignore b/.gitignore index eb749a7c..cd09790c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,23 @@ /.tools -/.vs +/build /src/Client/bin /src/Client/obj -/src/Website/.vs /src/Website/bin /src/Website/obj -/src/Hosted/css +/src/Hosted/assets/custom.css /src/Hosted/bin -/src/Hosted/obj -/src/Hosted/js /src/Hosted/css -/src/Hosted/scripts -/src/Hosted/node_modules +/src/Hosted/js /src/Hosted/legal +/src/Hosted/node_modules +/src/Hosted/obj /src/Hosted/posts -/build +/src/Hosted/scripts *.user -/.ionide *.bak* *.done +*.min.css +*.map +*.vs/ + +*.ionide* diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..ac111ae6 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,136 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build Solution in Release mode", + "type": "shell", + "command": "./build.sh", + "windows": { + "command": ".\\build.ps1" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "Build Solution in Debug mode", + "type": "shell", + "command": "./build.sh -deb", + "windows": { + "command": ".\\build.ps1 -deb" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "Build Project in Debug mode", + "type": "shell", + "command": "./build.sh -deb -project ${input:project}", + "windows": { + "command": ".\\build.ps1 -deb -project ${input:project}" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "Build Project in Release mode", + "type": "shell", + "command": "./build.sh -project ${input:project}", + "windows": { + "command": ".\\build.ps1 -project ${input:project}" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "Install with tools", + "type": "shell", + "command": "./install.sh", + "windows": { + "command": ".\\install.ps1" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "Install", + "type": "shell", + "command": "./install.sh -buildonly", + "windows": { + "command": ".\\install.ps1 -buildOnly" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "Run Hosted", + "type": "shell", + "command": "./run.sh", + "windows": { + "command": ".\\run.ps1" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "Serve as an offline sitelet", + "type": "shell", + "command": "./serve.sh", + "windows": { + "command": ".\\serve.ps1" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "CSS Server", + "type": "shell", + "command": "./grunt-watch.sh", + "windows": { + "command": ".\\grunt-watch.ps1" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + } + ], + "inputs": [ + { + "type": "pickString", + "id": "project", + "description": "Which project you want to build?", + "options": [ + "client", + "hosted", + "website" + ] + } + ] +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..d8e2dd92 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM mcr.microsoft.com/dotnet/sdk:3.1 + +# Update environment +RUN apt-get update + +# Install npm +RUN apt-get -y install curl gnupg +RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - +RUN apt-get -y install nodejs +RUN echo "NODE Version:" && node --version +RUN echo "NPM Version:" && npm --version + +# Create working directory +RUN mkdir /website + +# Copy content under /website from the root of the repo +COPY . /website + +WORKDIR /website + +# Exposing port used by the serve.sh +EXPOSE 56001 + +# Install, build and serve +CMD bash -c "./install.sh && ./build.sh && ls -a && ./serve.sh" \ No newline at end of file diff --git a/build.ps1 b/build.ps1 index 2997eed0..e264c5e3 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,17 +1,29 @@ -echo "Copy legal files" - -xcopy .\legal\site-docs\intellifactory.com\* .\src\Hosted\legal\ /s /e - -echo "Copy blog posts files" - -xcopy .\blogs\user\* .\src\Hosted\posts\ /s /e - -echo "Running npm install" - -pushd src/Hosted -npm install -popd +Param( + [Switch] + $deb, + [Parameter(Mandatory=$false)] + [ValidateSet("client", "hosted", "website")] + [String] + $project +) echo "Running dotnet build" -dotnet build SiteFi.sln +if ($project -ne "") { + if ($deb) { + echo "Running build in Debug mode..." + dotnet build "src\$project\$project.fsproj" --no-incremental -c Debug -v normal + } else { + echo "Running build in Release mode..." + dotnet build "src\$project\$project.fsproj" --no-incremental -v normal + } +} else { + if ($deb) { + echo "Running build in Debug mode..." + dotnet build SiteFi.sln --no-incremental -c Debug -v normal + } else { + echo "Running build in Release mode..." + dotnet build SiteFi.sln --no-incremental -v normal + } +} + diff --git a/build.sh b/build.sh index c69f7e2f..01d95397 100644 --- a/build.sh +++ b/build.sh @@ -1,24 +1,39 @@ #!/bin/bash -echo "Copy legal/site-docs/if.com/ under src/Hosted/legal/" - -cp -r legal/site-docs/intellifactory.com/ src/Hosted/legal/ - -echo "Copy blogposts under /src/Hosted/posts" - -cp -r blogs/user src/Hosted/posts - -echo "Installing dotnet-serve" - -dotnet tool install dotnet-serve --tool-path .tools - -echo "Running npm install" - -pushd src/Hosted -npm install -popd - echo "Running dotnet build" -dotnet build SiteFi.sln +if [[ $(echo "$2" | awk '{print toupper($0)}') = "-PROJECT" ]]; +then + if [[ $(echo "$3" | awk '{print toupper($0)}') = "CLIENT" ]] || [[ $(echo "$3" | awk '{print toupper($0)}') = "WEBSITE" ]] || [[ $(echo "$3" | awk '{print toupper($0)}') = "HOSTED" ]]; + then + if [[ $(echo "$1" | awk '{print toupper($0)}') = "-DEB" ]]; + then + dotnet build "src/$3/$3.fsproj" --no-incremental -c Debug -v normal + else + dotnet build "src/$3/$3.fsproj" --no-incremental -v normal + fi + else + >&2 echo "Incorrect project name" + exit 1 + fi +else + if [[ $(echo "$1" | awk '{print toupper($0)}') = "-PROJECT" ]]; + then + if [[ $(echo "$2" | awk '{print toupper($0)}') = "CLIENT" ]] || [[ $(echo "$2" | awk '{print toupper($0)}') = "WEBSITE" ]] || [[ $(echo "$2" | awk '{print toupper($0)}') = "HOSTED" ]]; + then + dotnet build "src/$2/$2.fsproj" --no-incremental -v normal + else + >&2 echo "Incorrect project name" + exit 1 + fi + else + if [[ $(echo "$1" | awk '{print toupper($0)}') = "-DEB" ]]; + then + dotnet build SiteFi.sln --no-incremental -c Debug -v normal + else + dotnet build SiteFi.sln --no-incremental -v normal + fi + fi +fi + diff --git a/docker.ps1 b/docker.ps1 new file mode 100644 index 00000000..f69f5b08 --- /dev/null +++ b/docker.ps1 @@ -0,0 +1,6 @@ +pushd src\Hosted +rm -rf node_modules +popd + +docker build -t website . +docker run -p 56001:56001 website \ No newline at end of file diff --git a/docker.sh b/docker.sh new file mode 100644 index 00000000..dff57065 --- /dev/null +++ b/docker.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Make sure the windows dependencies are not there +pushd src/Hosted +rm -rf node_modules +popd + +docker build -t website . +docker run -p 56001:56001 website \ No newline at end of file diff --git a/grunt-watch.ps1 b/grunt-watch.ps1 new file mode 100644 index 00000000..8fde8adf --- /dev/null +++ b/grunt-watch.ps1 @@ -0,0 +1,2 @@ +cd src/Hosted +npx grunt develop diff --git a/grunt-watch.sh b/grunt-watch.sh new file mode 100644 index 00000000..8fde8adf --- /dev/null +++ b/grunt-watch.sh @@ -0,0 +1,2 @@ +cd src/Hosted +npx grunt develop diff --git a/install.ps1 b/install.ps1 index d83d400f..b53fd102 100644 --- a/install.ps1 +++ b/install.ps1 @@ -2,9 +2,21 @@ param( [switch] $buildOnly ) +echo "Copy legal files" + +xcopy .\legal\site-docs\intellifactory.com\* .\src\Hosted\legal\ /s /e + +echo "Copy blog posts files" + +xcopy .\blogs\user\* .\src\Hosted\posts\ /s /e + +# Initialize git submodules +git submodule update --init --recursive + # Install npm packages pushd src\Hosted npm install +npx grunt popd if (!$buildOnly) { diff --git a/install.sh b/install.sh new file mode 100644 index 00000000..bd193508 --- /dev/null +++ b/install.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Initialize git submodules +git submodule update --init --recursive + +echo "Copy legal/site-docs/if.com/ under src/Hosted/legal/" +cp -rT legal/site-docs/intellifactory.com/ src/Hosted/legal/ + +echo "Copy blogposts under /src/Hosted/posts" +cp -rT blogs/user src/Hosted/posts + +# Install npm packages +pushd src/Hosted +npm install +npx grunt +popd + +if ! [[ $(echo "$1" | awk '{print toupper($0)}') = "-BUILDONLY" ]]; +then + # Install local dotnet-serve + dotnet tool install dotnet-serve --tool-path .tools +fi diff --git a/run.ps1 b/run.ps1 new file mode 100644 index 00000000..d33a3cd7 --- /dev/null +++ b/run.ps1 @@ -0,0 +1 @@ +dotnet run --project src\Hosted\Hosted.fsproj diff --git a/run.sh b/run.sh new file mode 100644 index 00000000..ea028f79 --- /dev/null +++ b/run.sh @@ -0,0 +1 @@ +dotnet run --project src/Hosted/Hosted.fsproj diff --git a/serve.ps1 b/serve.ps1 new file mode 100644 index 00000000..fb7e603d --- /dev/null +++ b/serve.ps1 @@ -0,0 +1 @@ +.tools/dotnet-serve.exe -d build -p:56001 --default-extensions:.html -a 0.0.0.0 diff --git a/serve.sh b/serve.sh new file mode 100644 index 00000000..b70af604 --- /dev/null +++ b/serve.sh @@ -0,0 +1 @@ +".tools/dotnet-serve" -d build -p:56001 --default-extensions:.html -a 0.0.0.0 diff --git a/src/Client/Client.fs b/src/Client/Client.fs index ac6297b7..b3eeddb9 100644 --- a/src/Client/Client.fs +++ b/src/Client/Client.fs @@ -2,8 +2,6 @@ open WebSharper open WebSharper.JavaScript -open WebSharper.UI -open WebSharper.UI.Notation module Highlight = open WebSharper.HighlightJS @@ -16,25 +14,6 @@ module Highlight = JS.Undefined ) -module Bulma = - - let DrawerShown = Var.Create false - - [] - let ToggleDrawer() = DrawerShown.Update not - - let HookDrawer() = - DrawerShown.View |> View.Sink (fun shown -> - JS.Document.QuerySelectorAll(".drawer-backdrop, .lhs-drawer").ForEach( - (fun (node, _, _, _) -> - let node = node :?> Dom.Element - "shown" - |> if shown then node.ClassList.Add else node.ClassList.Remove - ), - JS.Undefined - ) - ) - module Newsletter = let SignUpAction () = @@ -90,7 +69,6 @@ module Resizer = [] let Main() = - Bulma.HookDrawer() Highlight.Run() Newsletter.SignUpAction() Resizer.Resize() diff --git a/src/Client/Client.fsproj b/src/Client/Client.fsproj index 9163677a..596265b5 100644 --- a/src/Client/Client.fsproj +++ b/src/Client/Client.fsproj @@ -14,11 +14,15 @@ - - - - - + + + + + + + + + \ No newline at end of file diff --git a/src/Hosted/Gruntfile.js b/src/Hosted/Gruntfile.js index da762f8e..cad3b4f5 100644 --- a/src/Hosted/Gruntfile.js +++ b/src/Hosted/Gruntfile.js @@ -4,8 +4,40 @@ module.exports = function(grunt) { grunt.initConfig({ cssmin: { build: { - src: 'css/all.css', - dest: 'css/all.min.css' + files: [{ + expand: true, + cwd: 'assets', + src: ['*.css', '!*.min.css'], + dest: 'assets', + ext: '.min.css' + }, { + expand: true, + cwd: 'themekit/css', + src: ['*.css', '!*.min.css'], + dest: 'themekit/css', + ext: '.min.css' + }] + } + }, + sass: { + options: { + implementation: sass, + sourceMap: true + }, + dist: { + files: { + 'assets/custom.css': 'assets/custom.scss' + } + } + }, + watch: { + sass: { + files: ['**/*.scss'], + tasks: ['sass'] + }, + cssmin: { + files: ['**/*.css', '!**/*.min.css', '!**/*.scss'], + tasks: ['cssmin'] } } }); @@ -13,6 +45,8 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-sass'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.registerTask('default', ['cssmin']); + grunt.registerTask('develop', ['sass','cssmin','watch']); + grunt.registerTask('default', ['sass','cssmin']); }; \ No newline at end of file diff --git a/src/Hosted/Hosted.fsproj b/src/Hosted/Hosted.fsproj index f9fae6cb..67e7ab9c 100644 --- a/src/Hosted/Hosted.fsproj +++ b/src/Hosted/Hosted.fsproj @@ -5,11 +5,20 @@ + + + + - + + + + + + @@ -25,30 +34,25 @@ - - - - - - - + + + + + + - - - - - + \ No newline at end of file diff --git a/src/Hosted/Main.fs b/src/Hosted/Main.fs index a6fbecc6..364ba5c8 100644 --- a/src/Hosted/Main.fs +++ b/src/Hosted/Main.fs @@ -14,6 +14,7 @@ type BlogListingArgs = | [] LanguageAndIndex of string * int type EndPoint = + | [] Courses of slug:string | [] Trainings | [] Blogs of BlogListingArgs // User-less blog articles @@ -33,6 +34,10 @@ type EndPoint = | [] TermsOfUse | [] PrivacyPolicy | [] CookiePolicy + | [] Research + | [] Consulting + | [] Careers + | [] Job of string | [] Error404 | [] Debug @@ -116,7 +121,7 @@ module Markdown = .UseAdvancedExtensions() .Build() - let Convert content = Markdown.ToHtml(content, pipeline) + let Convert (content: string) = Markdown.ToHtml(content, pipeline) module Yaml = open System.Text.RegularExpressions @@ -352,7 +357,15 @@ module ClientSideCode = let map = new Map(el, options) let point = new LatLng(47.48543, 19.071336) let icon = Icon(Url = "/img/map-marker.png", Anchor = Point(8.0, 8.0)) - new Marker(MarkerOptions(point, Map = map, Title = "IntelliFactory", Icon = icon)) |> ignore + let infoWindow = InfoWindow(InfoWindowOptions(Content = Union2Of2 "IntelliFactory - Budapest office")) + let marker = new Marker(MarkerOptions(point, Map = map, Title = "IntelliFactory", Icon = icon)) + marker.AddListener("mouseover", fun _ -> + infoWindow.Open(map, marker) + ) |> ignore + infoWindow.AddListener("mouseout", fun _ -> + infoWindow.Close() + ) |> ignore + () ) ] [] @@ -363,11 +376,18 @@ module Site = type MainTemplate = Templating.Template<"../Hosted/index.html", serverLoad=Templating.ServerLoad.WhenChanged> type RedirectTemplate = Templating.Template<"../Hosted/redirect.html", serverLoad=Templating.ServerLoad.WhenChanged> type TrainingsTemplate = Templating.Template<"../Hosted/trainings.html", serverLoad=Templating.ServerLoad.WhenChanged> + type CourseBaseTemplate = Templating.Template<"../Hosted/course-base.html", serverLoad=Templating.ServerLoad.WhenChanged> type BlogListTemplate = Templating.Template<"../Hosted/bloglist.html", serverLoad=Templating.ServerLoad.WhenChanged> type UserBlogListTemplate = Templating.Template<"../Hosted/userbloglist.html", serverLoad=Templating.ServerLoad.WhenChanged> type BlogPostTemplate = Templating.Template<"../Hosted/blogpost.html", serverLoad=Templating.ServerLoad.WhenChanged> type ContactTemplate = Templating.Template<"../Hosted/contact.html", serverLoad=Templating.ServerLoad.WhenChanged> type LegalTemplate = Templating.Template<"../Hosted/legal.html", serverLoad=Templating.ServerLoad.WhenChanged> + type ResearchTemplate = Templating.Template<"../Hosted/research.html", serverLoad=Templating.ServerLoad.WhenChanged> + type ConsultingTemplate = Templating.Template<"../Hosted/consulting.html", serverLoad=Templating.ServerLoad.WhenChanged> + type CareersTemplate = Templating.Template<"../Hosted/careers.html", serverLoad=Templating.ServerLoad.WhenChanged> + type JobsBaseTemplate = Templating.Template<"../Hosted/jobs-base.html", serverLoad=Templating.ServerLoad.WhenChanged> + type TutorialLinkSnippetTemplate = Templating.Template<"../Hosted/tutorial-link-snippet.html", serverLoad=Templating.ServerLoad.WhenChanged> + type CategoriesTemplate = Templating.Template<"../Hosted/categories.html", serverLoad=Templating.ServerLoad.WhenChanged> type [] RawConfig = { @@ -417,7 +437,10 @@ module Site = Title: string Subtitle: string Abstract: string + AuthorName: string + User: string Url: string + AuthorUrl: string Content: string DateString: string SlugWithoutDate: string @@ -426,6 +449,7 @@ module Site = CategoryNumber: int Language: string Identity: int * int + TimeToRead: float } type BlogInfoRaw = @@ -588,13 +612,19 @@ module Site = id1, id2 | _ -> failwithf "Invalid identity found (%A)" entries + let timeToRead = + let words = content.Split([|' '|]).Length + Math.Ceiling(float words / 200.) // Avarage WPM is 200 eprintfn "DEBUG-ADD: (%s, %s)\n-------------------" user fname Map.add (user, fname) { Title = title Subtitle = subtitle Abstract = ``abstract`` + AuthorName = if config.Users.ContainsKey user then config.Users.[user] else user + User = user Url = url + AuthorUrl = Urls.USER_URL user Content = content DateString = datestring SlugWithoutDate = slug @@ -603,6 +633,7 @@ module Site = CategoryNumber = categoryNo Language = language Identity = identity + TimeToRead = timeToRead } map ) store else @@ -682,32 +713,10 @@ module Site = let private menubar(config: Config) = MainTemplate.Menubar() - .ShortTitle(config.ShortTitle) .Doc() - let ArticleBasePage langopt (config: Config) (pageTitle: option) hasBanner (transparentHeader: bool) articles (body: Doc) = - let head = head() - MainTemplate() -#if !DEBUG - .ReleaseMin(".min") -#endif - .IsTransparentHeader(if transparentHeader then "menu-transparent" else "") - // TODO: .NavbarOverlay(if hasBanner then "overlay-bar" else "") - .Head(head) - .MenuBar(menubar config) - .Title( - match pageTitle with - | None -> "" - | Some t -> t + " | " - ) - .Body(body) - .Cookie(Cookies.Banner false) - .FooterPlaceholder(MainTemplate.Footer().Doc()) - .Doc() - |> Content.Page - let BlogSidebar config articles (article: Article) = - MainTemplate.Sidebar() + BlogPostTemplate.SidebarTemplate() .Categories( // Render the categories widget iff there are categories if article.Categories.IsEmpty then @@ -715,7 +724,7 @@ module Site = else article.Categories |> List.map (fun category -> - MainTemplate.Category() + BlogPostTemplate.Category() .Name(category) .Url(Urls.CATEGORY category (URL_LANG config article.Language)) .Doc() @@ -725,14 +734,14 @@ module Site = // There is always at least one blog post, so we render this // section no matter what. .ArticleItems( - MainTemplate.ArticleItems() + BlogPostTemplate.ArticleItems() .ArticleItems( articles |> Map.toList |> List.sortByDescending (fun (_, item) -> item.Date) |> List.truncate 10 |> List.map (fun (_, item) -> - MainTemplate.ArticleItem() + BlogPostTemplate.ArticleItem() .Title(item.Title) .Url(item.Url) .Date(item.Date.ToShortDateString()) @@ -775,17 +784,21 @@ module Site = [] // Zero out if article has the master language let langopt = URL_LANG config article.Language - // MainTemplate.ArticlePage() - MainTemplate.ArticlePage() + let head = head() + BlogPostTemplate() +#if !DEBUG + .ReleaseMin(".min") +#endif + .IsTransparentHeader("menu-transparent") + .Head(head) + .Menubar(menubar config) + .Cookie(Cookies.Banner false) + .FooterPlaceholder(MainTemplate.Footer().Doc()) // Main content panel .Article( PLAIN article.Content - //MainTemplate.Article() - // .Title(article.Title) - // .Subtitle(Doc.Verbatim article.Subtitle) - // .Content(PLAIN article.Content) - // .Doc() ) + .TimeToRead(string article.TimeToRead) .SourceCodeUrl(sprintf "%s/tree/master%s.md" config.GitHubRepo article.Url) .LanguageSelectorPlaceholder( if languages.IsEmpty then @@ -809,13 +822,18 @@ module Site = ) .Doc() ) - .Date(article.DateString) + .Date(article.Date.ToString("MMM dd, yyyy")) .Title(article.Title) + .Description(article.Abstract) + .PageUrl(article.Url) + .AuthorName(article.AuthorName) + .AuthorUrl(article.AuthorUrl) .CategoryNo(string article.CategoryNumber) + .ServerUrl(config.ServerUrl) // Sidebar .Sidebar(BlogSidebar config articles article) .Doc() - |> ArticleBasePage langopt config (Some article.Title) false false articles + |> Content.Page // The silly ref's are needed because offline sitelets are // initialized in their own special way, without having access @@ -825,6 +843,11 @@ module Site = let __identities1 : Identities1 ref = ref Map.empty let __config : Config ref = ref <| ReadConfig() + let trainings = + DirectoryInfo("../Hosted/trainings/").EnumerateFiles("*.html", SearchOption.TopDirectoryOnly) + |> Seq.map (fun x -> x.Name.Substring(0, x.Name.Length-5)) + |> List.ofSeq + let Main (config: Config ref) (identities1: Identities1 ref) (info: BlogInfoRaw ref) (articles: Articles ref) = let getContent (ctx: Context<_>) fileName = use r = new StreamReader(Path.Combine(@"../Hosted/", "legal", fileName)) @@ -895,22 +918,101 @@ module Site = |> List.map fst |> sprintf "Trying to find page \"%s\" (with key=\"%s\"), but it's not in %A" p page |> Content.Text + let COURSES (slug: string) = + let page = + if slug.ToLower().EndsWith(".html") then + slug.Substring(0, slug.Length-5) + else + slug + let templateFile = Path.Combine (__SOURCE_DIRECTORY__, sprintf @"../Hosted/trainings/%s.html" page) + if File.Exists templateFile then + CourseBaseTemplate(File.ReadAllText templateFile) + |> fun template -> + let vids = + [ + "Asynchronous, concurrent and distributed programming" + "Concise error-handling, logging" + "Process data with composable functions" + "F#'s type inference" + "Pattern matching and Active Patterns" + "Pit of success with typing" + "Partial application and currying" + "Code quotations" + "Interactive shell and interpreter" + ] + |> List.map (fun x -> + TutorialLinkSnippetTemplate + .VideoItem() + .Title(x) + .Doc() + ) + template +#if !DEBUG + .ReleaseMin(".min") +#endif + .VideoList(vids) + .MenuBar(menubar config.Value) + .Footer(MainTemplate.Footer().Doc()) + .Cookie(Cookies.Banner false) + .Doc() + |> Content.Page + else + trainings + |> sprintf "Trying to find page \"%s\" (with key=\"%s\"), but it's not in %A" slug page + |> Content.Text let TRAININGS () = let mapStyles = mapStyles() let header = TrainingsTemplate.TrainingBody() .Map(client <@ ClientSideCode.TalksAndPresentations.GMap(mapStyles) @>) - .ImageSliderInit(client <@ ClientSideCode.Swiper.Init() @>) .Doc() TrainingsTemplate() +#if !DEBUG + .ReleaseMin(".min") +#endif .MenuBar(menubar config.Value) .HeaderContent(header) .Footer(MainTemplate.Footer().Doc()) .Cookie(Cookies.Banner false) .Doc() |> Content.Page + let JOB job = + if File.Exists("../Hosted/jobs/" + job + ".html") then + let writer = (System.Globalization.CultureInfo("en-US", false)).TextInfo; + let title = + job + .Substring(7) // Cut the job date prefix off - assumed to be "YYYYMM-" + .Replace("-", " ") // Reintroduce spaces + .Replace("fsharp", "F#") // Format F#/C# as such + .Replace("csharp", "C#") + |> writer.ToTitleCase // Capitalize each first letter + |> Uri.EscapeDataString // Escape so we can include it as a link + let content = File.ReadAllText("../Hosted/jobs/" + job + ".html") + JobsBaseTemplate(content) + #if !DEBUG + .ReleaseMin(".min") + #endif + .MenuBar(menubar config.Value) + .ApplySteps( + JobsBaseTemplate.StepsSidebar() + .PositionName(title) + .Doc() + ) + .Footer(MainTemplate.Footer().Doc()) + .Cookie(Cookies.Banner false) + .Doc() + |> Content.Page + else + Content.Page( + [ + p [] [text <| sprintf "Couldn't find source for job [%s]" job] + ] + ) let TERMSOFUSE (ctx: Context<_>) = LegalTemplate() +#if !DEBUG + .ReleaseMin(".min") +#endif .MenuBar(menubar config.Value) .HeaderContent(Doc.Empty) .Content(Doc.Verbatim <| Markdown.Convert (getContent ctx "TermsOfUse.md")) @@ -942,12 +1044,45 @@ module Site = let CONTACT () = let mapContactStyles = mapContactStyles() ContactTemplate() +#if !DEBUG + .ReleaseMin(".min") +#endif .MenuBar(menubar config.Value) .Map(client <@ ClientSideCode.TalksAndPresentations.GMapOffice(mapContactStyles) @>) .Footer(MainTemplate.Footer().Doc()) .Cookie(Cookies.Banner false) .Doc() |> Content.Page + let RESEARCH () = + ResearchTemplate() +#if !DEBUG + .ReleaseMin(".min") +#endif + .MenuBar(menubar config.Value) + .Footer(MainTemplate.Footer().Doc()) + .Cookie(Cookies.Banner false) + .Doc() + |>Content.Page + let CONSULTING () = + ConsultingTemplate() +#if !DEBUG + .ReleaseMin(".min") +#endif + .MenuBar(menubar config.Value) + .Footer(MainTemplate.Footer().Doc()) + .Cookie(Cookies.Banner false) + .Doc() + |>Content.Page + let CAREERS () = + CareersTemplate() +#if !DEBUG + .ReleaseMin(".min") +#endif + .MenuBar(menubar config.Value) + .Footer(MainTemplate.Footer().Doc()) + .Cookie(Cookies.Banner false) + .Doc() + |>Content.Page // pageNo is 1-based let BLOG_LISTING (banner: Doc) (pageNo: int) f = let as1 = @@ -968,6 +1103,9 @@ module Site = let isFirst = pageNo = 1 let isLast = List.length as1 - pageNo < 1 BlogListTemplate() +#if !DEBUG + .ReleaseMin(".min") +#endif .Menubar(menubar config.Value) .Banner(banner) .ArticleList(ARTICLES articles) @@ -1005,6 +1143,25 @@ module Site = |> Content.Page else Content.Text "Page out of bounds" + let CATEGORIES () = + CategoriesTemplate() + .MenuBar(menubar config.Value) + .Footer(MainTemplate.Footer().Doc()) + .Cookie(Cookies.Banner false) + .Tags( + info.Value.Categories + |> Map.toList + |> List.sortByDescending snd + |> List.map (fun (tag, count) -> + CategoriesTemplate.Tag() + .Title(tag) + .Url(Urls.CATEGORY tag "") + .Count(string count) + .Doc() + ) + ) + .Doc() + |> Content.Page let BLOG_LISTING_NO_PAGING (banner: Doc) f = BlogListTemplate() .Menubar(menubar config.Value) @@ -1090,8 +1247,12 @@ module Site = ] Application.MultiPage (fun (ctx: Context<_>) -> function + | Courses (site: string) -> + COURSES site | Trainings -> TRAININGS () + | Job job -> + JOB job | TermsOfUse -> TERMSOFUSE ctx | CookiePolicy -> @@ -1139,6 +1300,8 @@ module Site = else failwithf "Unable to find user for id1=%d, with map=%A" id1 identities1.Value REDIRECT_TO (Urls.OLD_TO_POST_URL (user, datestring, oldslug)) + | Categories -> + CATEGORIES () // Blog articles in a given category | Category (cat, langopt) -> BLOG_LISTING_NO_PAGING @@ -1149,8 +1312,6 @@ module Site = langopt = URL_LANG config.Value article.Language && List.contains cat article.Categories - | Categories -> - Content.NotFound // For a simple but useful reference on Atom vs RSS content, refer to: // https://www.intertwingly.net/wiki/pie/Rss20AndAtom10Compared | AtomFeed -> @@ -1193,6 +1354,12 @@ module Site = articles := _articles identities1 := ComputeIdentities1 articles.Value Content.Text "Articles/configs reloaded." + | Research -> + RESEARCH() + | Consulting -> + CONSULTING() + | Careers -> + CAREERS() | Error404 -> Content.File("../Hosted/404.html", AllowOutsideRootFolder=true) | Debug -> @@ -1207,6 +1374,9 @@ module Site = p [] [text <| sprintf "%A" info.Value] h2 [] [text "Identities"] p [] [text <| sprintf "%A" identities1.Value] + h2 [] [text "Articles"] + for ((user, slug), art) in Map.toList (!articles) do + p [] [text <| sprintf "%s/%s -> %s" user slug art.Title] ] ) ) @@ -1249,9 +1419,14 @@ type Website() = |> List.map (fst >> fst) |> Set.ofList |> Set.toList - eprintfn "DEBUG-users: %A" users + let jobs = + DirectoryInfo("../Hosted/jobs/").EnumerateFiles("*.html", SearchOption.TopDirectoryOnly) + |> Seq.map (fun x -> x.Name.Replace(".html", "")) + |> List.ofSeq [ // Generate the learning page + for training in Site.trainings do + Courses training Trainings // Generate contact page Contact @@ -1284,18 +1459,24 @@ type Website() = ) articles then Category (category, language) + Categories // Generate the RSS/Atom feeds RSSFeed AtomFeed for user in users do RSSFeedForUser user AtomFeedForUser user + for job in jobs do + Job job // Generate 404 page Error404 // Generate legal pages CookiePolicy TermsOfUse PrivacyPolicy + Research + Consulting + Careers ] [)>] diff --git a/src/Hosted/assets/404/css/styles-man.css b/src/Hosted/assets/404/css/styles-man.css index 948dc0a6..fe4bccdf 100644 --- a/src/Hosted/assets/404/css/styles-man.css +++ b/src/Hosted/assets/404/css/styles-man.css @@ -15,25 +15,10 @@ Theme: Animated Man    2. - Animation ------------------------------------------------------------------ */ -@font-face { - font-family: 'Jost'; - src: url('../../../media/fonts/Jost-Book.woff2') format('woff2'), url('media/fonts/Jost-Book.woff') format('woff'); - font-weight: 400; - font-style: normal; -} - -@font-face { - font-family: 'Jost'; - src: url('../../../media/fonts/Jost-Medium.woff2') format('woff2'), url('media/fonts/Jost-Medium.woff') format('woff'); - font-weight: 500; - font-style: normal; -} - /* ------------------     General setting --------------------*/ body { - font-family: 'Jost', 'Montserrat', sans-serif; background-color: #f8f9fb; } diff --git a/src/Hosted/assets/careers-1.jpg b/src/Hosted/assets/careers-1.jpg new file mode 100644 index 00000000..57db3299 Binary files /dev/null and b/src/Hosted/assets/careers-1.jpg differ diff --git a/src/Hosted/assets/careers-2.png b/src/Hosted/assets/careers-2.png new file mode 100644 index 00000000..f59bf460 Binary files /dev/null and b/src/Hosted/assets/careers-2.png differ diff --git a/src/Hosted/assets/classroom.jpg b/src/Hosted/assets/classroom.jpg new file mode 100644 index 00000000..fd3b7b3c Binary files /dev/null and b/src/Hosted/assets/classroom.jpg differ diff --git a/src/Hosted/assets/conferences/cefp-grey.png b/src/Hosted/assets/conferences/cefp-grey.png new file mode 100644 index 00000000..d7c77adc Binary files /dev/null and b/src/Hosted/assets/conferences/cefp-grey.png differ diff --git a/src/Hosted/assets/conferences/cefp.png b/src/Hosted/assets/conferences/cefp.png new file mode 100644 index 00000000..d8775118 Binary files /dev/null and b/src/Hosted/assets/conferences/cefp.png differ diff --git a/src/Hosted/assets/conferences/fp-bud-grey.png b/src/Hosted/assets/conferences/fp-bud-grey.png new file mode 100644 index 00000000..04a80065 Binary files /dev/null and b/src/Hosted/assets/conferences/fp-bud-grey.png differ diff --git a/src/Hosted/assets/conferences/fp-bud.png b/src/Hosted/assets/conferences/fp-bud.png new file mode 100644 index 00000000..a447158d Binary files /dev/null and b/src/Hosted/assets/conferences/fp-bud.png differ diff --git a/src/Hosted/assets/conferences/fpdays-grey.jpg b/src/Hosted/assets/conferences/fpdays-grey.jpg new file mode 100644 index 00000000..54c6222b Binary files /dev/null and b/src/Hosted/assets/conferences/fpdays-grey.jpg differ diff --git a/src/Hosted/assets/conferences/fpdays.jpg b/src/Hosted/assets/conferences/fpdays.jpg new file mode 100644 index 00000000..de8888d4 Binary files /dev/null and b/src/Hosted/assets/conferences/fpdays.jpg differ diff --git a/src/Hosted/assets/conferences/icfp-grey.png b/src/Hosted/assets/conferences/icfp-grey.png new file mode 100644 index 00000000..40d1c913 Binary files /dev/null and b/src/Hosted/assets/conferences/icfp-grey.png differ diff --git a/src/Hosted/assets/conferences/icfp.png b/src/Hosted/assets/conferences/icfp.png new file mode 100644 index 00000000..1ee6f08c Binary files /dev/null and b/src/Hosted/assets/conferences/icfp.png differ diff --git a/src/Hosted/assets/consulting-1.jpg b/src/Hosted/assets/consulting-1.jpg new file mode 100644 index 00000000..622d1bbb Binary files /dev/null and b/src/Hosted/assets/consulting-1.jpg differ diff --git a/src/Hosted/assets/consulting-2-thumbnail.jpg b/src/Hosted/assets/consulting-2-thumbnail.jpg new file mode 100644 index 00000000..76a67ff9 Binary files /dev/null and b/src/Hosted/assets/consulting-2-thumbnail.jpg differ diff --git a/src/Hosted/assets/consulting-2.jpg b/src/Hosted/assets/consulting-2.jpg new file mode 100644 index 00000000..20994a29 Binary files /dev/null and b/src/Hosted/assets/consulting-2.jpg differ diff --git a/src/Hosted/assets/consulting-3-thumbnail.jpg b/src/Hosted/assets/consulting-3-thumbnail.jpg new file mode 100644 index 00000000..22c861c1 Binary files /dev/null and b/src/Hosted/assets/consulting-3-thumbnail.jpg differ diff --git a/src/Hosted/assets/consulting-3.jpg b/src/Hosted/assets/consulting-3.jpg new file mode 100644 index 00000000..83421589 Binary files /dev/null and b/src/Hosted/assets/consulting-3.jpg differ diff --git a/src/Hosted/assets/consulting-4-thumbnail.jpg b/src/Hosted/assets/consulting-4-thumbnail.jpg new file mode 100644 index 00000000..e03aabfc Binary files /dev/null and b/src/Hosted/assets/consulting-4-thumbnail.jpg differ diff --git a/src/Hosted/assets/consulting-4.jpg b/src/Hosted/assets/consulting-4.jpg new file mode 100644 index 00000000..6dc711d3 Binary files /dev/null and b/src/Hosted/assets/consulting-4.jpg differ diff --git a/src/Hosted/assets/consulting-5-thumbnail.jpg b/src/Hosted/assets/consulting-5-thumbnail.jpg new file mode 100644 index 00000000..6c28d90b Binary files /dev/null and b/src/Hosted/assets/consulting-5-thumbnail.jpg differ diff --git a/src/Hosted/assets/consulting-5.jpg b/src/Hosted/assets/consulting-5.jpg new file mode 100644 index 00000000..36ccf965 Binary files /dev/null and b/src/Hosted/assets/consulting-5.jpg differ diff --git a/src/Hosted/assets/consulting-6.jpg b/src/Hosted/assets/consulting-6.jpg new file mode 100644 index 00000000..c599fad1 Binary files /dev/null and b/src/Hosted/assets/consulting-6.jpg differ diff --git a/src/Hosted/assets/consulting-7.jpg b/src/Hosted/assets/consulting-7.jpg new file mode 100644 index 00000000..7c7dd228 Binary files /dev/null and b/src/Hosted/assets/consulting-7.jpg differ diff --git a/src/Hosted/assets/consulting-8.jpg b/src/Hosted/assets/consulting-8.jpg new file mode 100644 index 00000000..f50175e7 Binary files /dev/null and b/src/Hosted/assets/consulting-8.jpg differ diff --git a/src/Hosted/assets/contact-map-styles.json b/src/Hosted/assets/contact-map-styles.json index cf3e2c86..adac5aa9 100644 --- a/src/Hosted/assets/contact-map-styles.json +++ b/src/Hosted/assets/contact-map-styles.json @@ -1 +1,170 @@ -[{"featureType":"administrative","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"administrative.country","elementType":"geometry.stroke","stylers":[{"color":"#f2f2f2"}, {"visibility":"on"}]},{"featureType":"administrative.province","elementType":"geometry.stroke","stylers":[{"visibility":"off"}]},{"featureType":"landscape","elementType":"geometry","stylers":[{"visibility":"on"},{"color":"#e3e3e3"}]},{"featureType":"landscape.natural","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"poi","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"all","stylers":[{"color":"#cccccc"}]},{"featureType":"road","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit.line","elementType":"geometry","stylers":[{"visibility":"off"}]},{"featureType":"transit.line","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"transit.station.airport","elementType":"geometry","stylers":[{"visibility":"off"}]},{"featureType":"transit.station.airport","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"geometry","stylers":[{"color":"#FFFFFF"}]},{"featureType":"water","elementType":"labels","stylers":[{"visibility":"off"}]}] \ No newline at end of file +[ + { + "featureType": "all", + "elementType": "geometry.fill", + "stylers": [ + { + "weight": "2.00" + } + ] + }, + { + "featureType": "all", + "elementType": "geometry.stroke", + "stylers": [ + { + "color": "#9c9c9c" + } + ] + }, + { + "featureType": "all", + "elementType": "labels.text", + "stylers": [ + { + "visibility": "on" + } + ] + }, + { + "featureType": "landscape", + "elementType": "all", + "stylers": [ + { + "color": "#f2f2f2" + } + ] + }, + { + "featureType": "landscape", + "elementType": "geometry.fill", + "stylers": [ + { + "color": "#ffffff" + } + ] + }, + { + "featureType": "landscape.man_made", + "elementType": "geometry.fill", + "stylers": [ + { + "color": "#ffffff" + } + ] + }, + { + "featureType": "poi", + "elementType": "all", + "stylers": [ + { + "visibility": "off" + } + ] + }, + { + "featureType": "road", + "elementType": "all", + "stylers": [ + { + "saturation": -100 + }, + { + "lightness": 45 + } + ] + }, + { + "featureType": "road", + "elementType": "geometry.fill", + "stylers": [ + { + "color": "#eeeeee" + } + ] + }, + { + "featureType": "road", + "elementType": "labels.text.fill", + "stylers": [ + { + "color": "#7b7b7b" + } + ] + }, + { + "featureType": "road", + "elementType": "labels.text.stroke", + "stylers": [ + { + "color": "#ffffff" + } + ] + }, + { + "featureType": "road.highway", + "elementType": "all", + "stylers": [ + { + "visibility": "simplified" + } + ] + }, + { + "featureType": "road.arterial", + "elementType": "labels.icon", + "stylers": [ + { + "visibility": "off" + } + ] + }, + { + "featureType": "transit", + "elementType": "all", + "stylers": [ + { + "visibility": "off" + } + ] + }, + { + "featureType": "water", + "elementType": "all", + "stylers": [ + { + "color": "#46bcec" + }, + { + "visibility": "on" + } + ] + }, + { + "featureType": "water", + "elementType": "geometry.fill", + "stylers": [ + { + "color": "#c8d7d4" + } + ] + }, + { + "featureType": "water", + "elementType": "labels.text.fill", + "stylers": [ + { + "color": "#070707" + } + ] + }, + { + "featureType": "water", + "elementType": "labels.text.stroke", + "stylers": [ + { + "color": "#ffffff" + } + ] + } +] \ No newline at end of file diff --git a/src/Hosted/assets/custom.css b/src/Hosted/assets/custom.css deleted file mode 100644 index 0aeec1ac..00000000 --- a/src/Hosted/assets/custom.css +++ /dev/null @@ -1,413 +0,0 @@ -table>tbody>tr>td, table>tbody>tr>th, table>tfoot>tr>td, table>tfoot>tr>th, table>thead>tr>td, table>thead>tr>th { - padding: 8px; - line-height: 1.42857143; - vertical-align: top; - border-top: 1px solid #ddd; -} - -.tabs { - display: flex !important; - flex-wrap: wrap !important; -} - -.tabs div { - margin-right: 0.5em; - margin-bottom: 0.5em; - border-bottom: 1px transparent solid; - transition: all .5s; -} - -.tabs div a { - color: white; - display: block; - position: relative; - text-decoration: none; - border-radius: 15px; - cursor: pointer; - transition: all .5s; - background-color: rgb(71, 178, 228); - padding: 0.25em 0.75em -} - -.blog-tag { - text-transform: uppercase; - font-size: 0.75em; - text-align: center; - z-index: 1; - display: inline-block; - position: relative; - line-height: 1; -} - -.blog-tag:after { - content: ""; - position: absolute; - bottom: 0; - left: 0; - width: 100%; - background-color: lightblue; - z-index: -1; -} - -.flat-card { - width: 100%; - padding: 8px; - transition: all 0.3s; -} - - .flat-card .flat-card-content { - background-color: white; - /* box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05);*/ - } - -.blog-meta, .blog-title { - text-align: center; -} - -.masonry-item { - width: 100%; -} - -.tag-holder { - text-align: center; -} - -.blog-tag.orange:after { - background-color: orange; -} - -.section-header { - display: flex; - align-items: center; -} - -.section-header hr { - flex: 1; - margin-left: 1em; -} - -.menu-inner-image li a span { - margin-top: 10px; - margin-bottom: unset; -} - -@media (min-width: 576px) { - .masonry-item { - width: 50%; - } -} - -@media (min-width: 768px) { - .masonry-item { - width: 33%; - } -} - -.pagination .prev, .pagination .next { - display: list-item !important; -} - -.blog-title h3 { - cursor: pointer; - display: inline -} - -.blog-title a:hover { - color: rgb(71, 178, 228) -} - -.blog-title a { - color: black; - text-decoration: none; - transition: color 1s; -} - -.blog-title h3 + a { - margin-left: 0.25em; -} - -.blog-title h3 a:hover { - text-decoration: none; -} - -.popup-image { - overflow: hidden; - position: relative; - display: flex; -} - -.popup-image img { - min-width: 100%; - min-height: 100%; - transform: translate(-50%, 0%); - position: relative; - left: 50%; - top: 50%; - opacity: 25%; - transition: all 1s; -} - -.flat-card:hover .popup-image img { - transform: translate(-50%, 0%) scale(1.25); - opacity: 100%; -} - -.flat-card:hover { - margin-top: -10px; -} - -.trainings-map .inner-map { - height: 500px; - width: 100%; -} - -#image-slider { - margin: 0; - padding: 0; - background-color: #ccc; - height: 250px; -} - -#image-slider .swiper-container { - width: 100%; - height: 100%; -} - -#image-slider .swiper-wrapper { - margin-bottom: 0; -} - -#image-slider .swiper-slide { - text-align: center; - width: auto; -} - -#image-slider .swiper-slide img { - width: auto; - height: 250px; -} - -nav.menu-transparent:not(.scroll-menu) :not(.mega-dropdown) .menu-cnt > ul > li > a { - color: rgb(71, 178, 228) !important; -} - -h1:not(:first-child), h2:not(:first-child), h3:not(:first-child), h4:not(:first-child), h5:not(:first-child) { - margin-top: 45px; -} - -body > nav .menu-brand { - padding-top: 4px; - padding-bottom: 4px; -} - -.menu-brand a { - display: flex; - align-items: center; -} - -.menu-brand a span { - margin-left: 8px; - font-size: 1.25em; -} - -li pre { - margin: 0; -} - -li pre code { - padding: 0 !important; -} - -blockquote { - background-color: rgb(241, 245, 247); - border-left: 4px rgb(55, 81, 126) solid; - font-size: 21px; - line-height: 1.6; -} - -blockquote { - padding: 10px 20px; - margin-left: 0; - position: relative; - padding-left: 50px; -} - -blockquote:before { - content: "\65"; - font-family: "Icons"; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - speak: none; - text-transform: none; - position: absolute; - margin-left: -30px; -} - -li > p:last-child, li > ul:last-child, li > ol:last-child, li > pre:last-child, li > div:last-child { - margin-bottom: 1em; -} - -li > pre:not(:first-child) { - margin-top: 1em; - margin-bottom: 1em; -} - -.success-box.visible { - display: block !important; -} - -.error-box.visible { - display: block !important; -} - - -.mega-open-source .panel { - display: flex; -} - -.mega-open-source .description { - color: black; - text-align: left; -} - -.mega-open-source img { - text-align: left; - display: block; -} - -/* BEGIN: COOKIE BANNER */ -#cookie-banner { - position: fixed; - z-index: 1000; - left: 0; - right: 0; - bottom: 0; - background: #202020; - color: white; - display: none; - flex-direction: row; - align-items: center; -} - -#cookie-banner > p { - flex: 1; -} - -#cookie-banner a { - color: #3273dc; - cursor: pointer; - text-decoration: none; -} - -#cookie-banner > * { - margin: 10px; -} - -#cookie-banner button { - box-shadow: none; - padding: 5px 12px; - color: #363636; - border-radius: 3px; - border: 1px solid #dbdbdb; - background-color: white; - font-size: 16px; -} - -#cookie-banner button + button { - margin-left: 10px; -} - -@media screen and (max-width: 767px) { - #cookie-banner { - flex-direction: column; - } -} -/* END: COOKIE BANNER */ - -.legal-header+.section-base .container { - padding-top: 0; -} - -.legal-header .container { - padding-top: 50px; - padding-bottom: 50px; -} - -/* Long text blocks (``` ... ```) - use a H scrollbar */ -pre:not(.hljs) { - overflow-x: auto; -} - -/* Blog author list */ -.menu-inner-vertical.authors ul li { - border-top: 1px solid #bbb; -} - .menu-inner-vertical.authors ul li a { - color: rgb(71, 178, 228); - } - - .menu-inner-vertical.authors ul li a img { - vertical-align: text-bottom; - } - -#signUp:not(.loading) .fa-spin { - display: none; -} - -#signUp.loading span { - display: none; -} - -.icon-social a i { - transform: translateX(-50%) translateY(-50%); -} - -.social-colors.icon-links-button .vimeo:not(:hover), .social-colors-hover.icon-links-button .vimeo:hover, -.social-colors.icon-links-grid .vimeo:not(:hover), .social-colors-hover.icon-links-grid .vimeo:hover { - background-color: #464646; - border-color: #464646; - color: #FFF; -} - -@media (max-width: 991.98px) { - .dropdown:hover > a:after, .menu-cnt li.active:hover > a:after { - transform: translateY(-50%) rotate(90deg) matrix(-1, 0, 0, 1, 0, 0); - } -} - -.form-ajax .success-box, .form-ajax .error-box { - display: none; - margin-top: 20px; -} -.user-information { - text-align: center; - margin-top: 60px; -} - -.user-name { - font-size: 400%; - margin-bottom: 20px; - line-height: 100%; - color: black; -} - -.user-social i { - color: rgb(102, 102, 102); -} - -.user-top a:not(:first-child) { - margin-left: 10px; -} - -.user-profile-picture { - max-width: 200px; - margin-bottom: 20px; - margin-left: auto; - margin-right: auto; -} - -.user-profile-picture img { - border-radius: 50%; -} \ No newline at end of file diff --git a/src/Hosted/assets/custom.scss b/src/Hosted/assets/custom.scss new file mode 100644 index 00000000..982965fb --- /dev/null +++ b/src/Hosted/assets/custom.scss @@ -0,0 +1,748 @@ +table { + & > thead, + & > tbody, + & > tfoot { + & > tr { + & > td, + & > th { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; + } + } + } +} + +.tabs { + display: flex !important; + flex-wrap: wrap !important; + + &.tabs-without-count { + div { + a { + border-radius: 15px; + } + } + } + + div { + margin-right: 0.5em; + margin-bottom: 0.5em; + border-bottom: 1px transparent solid; + transition: all 0.5s; + + a { + color: #ffffff; + display: inline-block; + position: relative; + text-decoration: none; + border-top-left-radius: 15px; + border-bottom-left-radius: 15px; + cursor: pointer; + transition: all 0.5s; + background-color: #47b2e4; + padding: 0.25em 0.75em 0.25em 0.75em; + } + + span { + background-color: #4bc6ff; + border-top-right-radius: 15px; + border-bottom-right-radius: 15px; + padding: 0.25em 0.75em 0.25em 0.75em; + color: #ffffff; + display: inline-block; + } + } +} + +.blog-tag { + text-transform: uppercase; + font-size: 0.75em; + text-align: center; + z-index: 1; + display: inline-block; + position: relative; + line-height: 1; + + &:after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + background-color: #add8e6; + z-index: -1; + } + + &.orange:after { + background-color: #ffa500; + } +} + +#image-slider { + margin: 0; + padding: 0; + background-color: #cccccc; + height: 250px; + + .swiper-container { + width: 100%; + height: 100%; + } + + .swiper-wrapper { + margin-bottom: 0; + } + + .swiper-slide { + text-align: center; + width: auto; + + img { + width: auto; + height: 250px; + } + } +} + +.flat-card { + width: 100%; + padding: 8px; + transition: all 0.3s; + + &:hover { + margin-top: -10px; + } + + .flat-card-content { + background-color: #ffffff; + /* box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05);*/ + } +} + +blockquote { + background-color: #f1f5f7; + border-left: 4px #37517e solid; + font-size: 21px; + line-height: 1.6; + padding: 10px 20px; + margin-left: 0; + position: relative; + padding-left: 50px; + + &:before { + content: '\65'; + font-family: 'Icons'; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + speak: none; + text-transform: none; + position: absolute; + margin-left: -30px; + } +} + +.menu-inner-vertical.authors { + ul { + li { + border-top: 1px solid #bbb; + a { + color: #47b2e4; + + img { + vertical-align: text-bottom; + } + } + } + } +} + +.masonry-item { + width: 100%; + + @media (min-width: 576px) { + width: 50%; + } + + @media (min-width: 768px) { + width: 33%; + } +} + +.section-header { + display: flex; + align-items: center; + + hr { + flex: 1; + margin-left: 1em; + } +} + +.menu-inner-image { + li { + a { + span { + margin-top: 10px; + margin-bottom: unset; + } + } + } +} + +.pagination { + .prev, + .next { + display: list-item !important; + } +} + +.popup-image { + overflow: hidden; + position: relative; + display: flex; + + img { + min-width: 100%; + min-height: 100%; + transform: translate(-50%, 0%); + position: relative; + left: 50%; + top: 50%; + opacity: 25%; + transition: all 1s; + + .flat-card:hover & { + transform: translate(-50%, 0%) scale(1.25); + opacity: 100%; + } + } +} + +.blog-meta { + text-align: center; +} + +.blog-title { + text-align: center; + + h3 { + cursor: pointer; + display: inline; + + & + a { + margin-left: 0.25em; + } + + & a:hover { + text-decoration: none; + } + } + + a { + color: #000000; + text-decoration: none; + transition: color 1s; + + &:hover { + color: #47b2e4; + } + } +} + +.tag-holder { + text-align: center; +} + +.trainings-map { + .inner-map { + height: 500px; + width: 100%; + } +} + +.menu-brand { + a { + display: flex; + align-items: center; + + span { + margin-left: 8px; + font-size: 1.25em; + } + } + + body > nav & { + padding-top: 4px; + padding-bottom: 4px; + } +} + +li { + pre { + margin: 0; + + code { + padding: 0 !important; + } + + &:not(:first-child) { + margin-top: 1em; + margin-bottom: 1em; + } + } + + p, + ul, + ol, + pre, + div:not(.mega-menu):not(.panel) { + &:last-child { + margin-bottom: 1em; + } + } +} + +.mega-open-source { + .panel { + display: flex; + margin-bottom: 0px; + } + + .description { + color: #000000; + text-align: left; + } + + img { + text-align: left; + display: block; + } + + & > a, + .menu-cnt > ul > &.active > a { + @media screen and (max-width: 992px) { + nav.light & { + color: #444444 !important; + } + + nav.dark & { + color: #47b2e4 !important; + } + } + } +} + +.success-box, +.error-box { + &.visible { + display: block !important; + } +} + +#cookie-banner { + position: fixed; + z-index: 1000; + left: 0; + right: 0; + bottom: 0; + background: #202020; + color: #ffffff; + display: none; + flex-direction: row; + align-items: center; + + & > p { + flex: 1; + } + + a { + color: #3273dc; + cursor: pointer; + text-decoration: none; + } + + & > * { + margin: 10px; + } + + button { + box-shadow: none; + padding: 5px 12px; + color: #363636; + border-radius: 3px; + border: 1px solid #dbdbdb; + background-color: #ffffff; + font-size: 16px; + + & + button { + margin-left: 10px; + } + } + + @media screen and (max-width: 767px) { + flex-direction: column; + } +} + +.legal-header { + & + .section-base { + .container { + padding-top: 0; + } + } + + .container { + padding-top: 50px; + padding-bottom: 50px; + } +} + +pre { + &:not(.hljs) { + overflow-x: auto; + } +} + +.icon-social { + a { + i { + transform: translateX(-50%) translateY(-50%); + } + } +} + +#signUp { + &:not(.loading) { + .fa-spin { + display: none; + } + } + &.loading { + span { + display: none; + } + } +} + +.social-colors, +.social-colors-hover { + &.icon-links-button, + &.icon-links-grid { + .vimeo { + &:not(:hover), + &:hover { + background-color: #464646; + border-color: #464646; + color: #ffffff; + } + } + } +} + +h1, +h2, +h3, +h4, +h5 { + &:not(:first-child) { + margin-top: 45px; + } +} + +nav.dark { + .menu-cnt { + & > ul { + & > li { + & > a { + color: #47b2e4 !important; + } + } + } + } +} +nav.light { + &.menu-transparent { + &:not(.scroll-menu) { + &:not(.mega-dropdown) { + .menu-cnt { + & > ul { + & > li { + & > a { + @media screen and (min-width: 992px) { + color: white !important; + } + } + } + } + } + } + } + } +} + +.form-ajax { + .success-box, + .error-box { + display: none; + margin-top: 20px; + } +} +.user-information { + text-align: center; + margin-top: 120px; + margin-bottom: 20px; +} + +.user-name { + font-size: 400%; + margin-bottom: 20px; + line-height: 100%; + color: #000000; +} + +.user-social { + i { + color: #666666; + } + a { + padding: 10px 20px 10px 20px; + text-decoration: none; + color: cornflowerblue; + font-weight: bold; + background-color: aliceblue; + } + a.rss i { + color: tomato; + } + a.atom i { + color: royalblue; + } +} + +.user-top { + a { + &:not(:first-child) { + margin-left: 10px; + } + } +} + +.user-profile-picture { + max-width: 200px; + margin-bottom: 20px; + margin-left: auto; + margin-right: auto; + + img { + border-radius: 50%; + } +} + +.open-source-item { + display: flex; + margin-bottom: 0px !important; + @media (max-width: 991.98px) { + padding-left: 30px; + nav.dark & a { + color: #47b2e4 !important; + } + } + + &:not(:last-child) { + border-right: #d4d3d3 solid 1px; + @media (max-width: 991.98px) { + border-right: none; + } + } + & > img { + margin-right: 10px; + } + & > div { + flex: 1; + } + & a { + padding-left: 0px; + } +} + +.dropdown:hover, +.menu-cnt li.active:hover { + & > a:after { + @media (max-width: 991.98px) { + transform: translateY(-50%) rotate(90deg) matrix(-1, 0, 0, 1, 0, 0); + } + } +} + +.menu-title { + color: white; + text-decoration: none; + + .menu-transparent:not(.scroll-menu) &, + .dark & { + color: #47b2e4; + } + + .title-alternative { + color: #ccc; + margin-left: 0px; + font-size: 1em; + } +} + +.cnt-box-team { + .caption { + h2 { + &::before { + content: none; + } + } + } +} + +.custom-timeline { + position: relative; + list-style: none; + padding: 0; + + &:before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + width: 5px; + background: #aaaaaa; + left: 20%; + margin-left: -10px; + + @media screen and (max-width: 760px) { + display: none; + } + } + + & li { + position: relative; + } + + .year { + display: block; + width: 25%; + padding-right: 100px; + position: absolute; + top: 1em; + text-align: right; + font-size: 1.5em; + color: #587790; + + @media screen and (max-width: 760px) { + display: none; + } + } + + .tl-content { + margin: 0 0 15px 25%; + color: #587790; + padding: 0.5em 2em 0.5em 1em; + font-weight: 300; + line-height: 1.4; + position: relative; + border-radius: 5px; + + h2 { + margin-top: 0px; + padding: 0 0 10px 0; + border-bottom: 1px solid #aaaaaa; + } + + @media screen and (max-width: 760px) { + margin: 0px; + } + } + + .tl-small-date { + display: none; + + @media screen and (max-width: 760px) { + display: inline-block; + } + } +} + +.sponsor-logo { + position: absolute; + top: 50%; + left: 50%; + transform: translateX(-50%) translateY(-50%); + + &-holder { + height: 20vh; + position: relative; + } + + &-fpbud { + max-width: 60% !important; + } + + &-icfp { + max-width: 100% !important; + } + + &-fpdays { + max-width: 50% !important; + } + + &-cefp { + max-width: 100% !important; + } +} + +.cnt-box-team, +.cnt-box-team:hover { + .caption { + @media screen and (max-width: 992px) { + height: unset; + position: unset; + padding-top: 0px; + } + } +} + +.blog-meta-icon { + width: max-content; + padding: 0 15px 15px 0; + + .blog-meta-date { + display: inline; + } + + i { + margin-right: 10px; + } + + a { + text-decoration: none; + color: #7e96a9 !important; + } + + div { + display: inline !important; + } +} + +.footer-last-section { + display: flex; + flex-wrap: revert; + + @media screen and (max-width: 776px) { + display: block; + } +} + +.footer-made-with { + flex: 1; + align-self: center; +} diff --git a/src/Hosted/assets/fsharp-training-1.jpg b/src/Hosted/assets/fsharp-training-1.jpg new file mode 100644 index 00000000..73f5b21f Binary files /dev/null and b/src/Hosted/assets/fsharp-training-1.jpg differ diff --git a/src/Hosted/assets/intern-position-1.jpg b/src/Hosted/assets/intern-position-1.jpg new file mode 100644 index 00000000..9f57976e Binary files /dev/null and b/src/Hosted/assets/intern-position-1.jpg differ diff --git a/src/Hosted/assets/media/fonts/Jost-Black.woff b/src/Hosted/assets/media/fonts/Jost-Black.woff deleted file mode 100644 index ff557dae..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Black.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Black.woff2 b/src/Hosted/assets/media/fonts/Jost-Black.woff2 deleted file mode 100644 index f882fed0..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Black.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-BlackItalic.woff b/src/Hosted/assets/media/fonts/Jost-BlackItalic.woff deleted file mode 100644 index 9cae086f..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-BlackItalic.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-BlackItalic.woff2 b/src/Hosted/assets/media/fonts/Jost-BlackItalic.woff2 deleted file mode 100644 index b301f101..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-BlackItalic.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Bold.woff b/src/Hosted/assets/media/fonts/Jost-Bold.woff deleted file mode 100644 index 6693da2a..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Bold.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Bold.woff2 b/src/Hosted/assets/media/fonts/Jost-Bold.woff2 deleted file mode 100644 index 7fd3b325..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Bold.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-BoldItalic.woff b/src/Hosted/assets/media/fonts/Jost-BoldItalic.woff deleted file mode 100644 index e1c03341..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-BoldItalic.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-BoldItalic.woff2 b/src/Hosted/assets/media/fonts/Jost-BoldItalic.woff2 deleted file mode 100644 index ea446bf2..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-BoldItalic.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Book.woff b/src/Hosted/assets/media/fonts/Jost-Book.woff deleted file mode 100644 index 91505621..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Book.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Book.woff2 b/src/Hosted/assets/media/fonts/Jost-Book.woff2 deleted file mode 100644 index dc1a6851..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Book.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-BookItalic.woff b/src/Hosted/assets/media/fonts/Jost-BookItalic.woff deleted file mode 100644 index c0cb0b18..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-BookItalic.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-BookItalic.woff2 b/src/Hosted/assets/media/fonts/Jost-BookItalic.woff2 deleted file mode 100644 index fb7080ec..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-BookItalic.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Hairline.woff b/src/Hosted/assets/media/fonts/Jost-Hairline.woff deleted file mode 100644 index 4ed0b0e0..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Hairline.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Hairline.woff2 b/src/Hosted/assets/media/fonts/Jost-Hairline.woff2 deleted file mode 100644 index 94806eea..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Hairline.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-HairlineItalic.woff b/src/Hosted/assets/media/fonts/Jost-HairlineItalic.woff deleted file mode 100644 index 7a1f6615..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-HairlineItalic.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-HairlineItalic.woff2 b/src/Hosted/assets/media/fonts/Jost-HairlineItalic.woff2 deleted file mode 100644 index 31fd3094..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-HairlineItalic.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Heavy.woff b/src/Hosted/assets/media/fonts/Jost-Heavy.woff deleted file mode 100644 index 52696501..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Heavy.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Heavy.woff2 b/src/Hosted/assets/media/fonts/Jost-Heavy.woff2 deleted file mode 100644 index 36effce0..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Heavy.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-HeavyItalic.woff b/src/Hosted/assets/media/fonts/Jost-HeavyItalic.woff deleted file mode 100644 index 0d014670..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-HeavyItalic.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-HeavyItalic.woff2 b/src/Hosted/assets/media/fonts/Jost-HeavyItalic.woff2 deleted file mode 100644 index ae15214c..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-HeavyItalic.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Light.woff b/src/Hosted/assets/media/fonts/Jost-Light.woff deleted file mode 100644 index b99b5e4f..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Light.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Light.woff2 b/src/Hosted/assets/media/fonts/Jost-Light.woff2 deleted file mode 100644 index a99f8bc2..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Light.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-LightItalic.woff b/src/Hosted/assets/media/fonts/Jost-LightItalic.woff deleted file mode 100644 index c67c4868..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-LightItalic.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-LightItalic.woff2 b/src/Hosted/assets/media/fonts/Jost-LightItalic.woff2 deleted file mode 100644 index d8e611f4..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-LightItalic.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Medium.woff b/src/Hosted/assets/media/fonts/Jost-Medium.woff deleted file mode 100644 index 92d064e4..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Medium.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Medium.woff2 b/src/Hosted/assets/media/fonts/Jost-Medium.woff2 deleted file mode 100644 index 21be610d..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Medium.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-MediumItalic.woff b/src/Hosted/assets/media/fonts/Jost-MediumItalic.woff deleted file mode 100644 index c447f021..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-MediumItalic.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-MediumItalic.woff2 b/src/Hosted/assets/media/fonts/Jost-MediumItalic.woff2 deleted file mode 100644 index 6cffb504..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-MediumItalic.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Semi.woff b/src/Hosted/assets/media/fonts/Jost-Semi.woff deleted file mode 100644 index b65d3dfa..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Semi.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Semi.woff2 b/src/Hosted/assets/media/fonts/Jost-Semi.woff2 deleted file mode 100644 index 406cd94d..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Semi.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-SemiItalic.woff b/src/Hosted/assets/media/fonts/Jost-SemiItalic.woff deleted file mode 100644 index bf28bb49..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-SemiItalic.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-SemiItalic.woff2 b/src/Hosted/assets/media/fonts/Jost-SemiItalic.woff2 deleted file mode 100644 index 2ccb3419..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-SemiItalic.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Thin.woff b/src/Hosted/assets/media/fonts/Jost-Thin.woff deleted file mode 100644 index 2d28375e..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Thin.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-Thin.woff2 b/src/Hosted/assets/media/fonts/Jost-Thin.woff2 deleted file mode 100644 index 4b56178a..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-Thin.woff2 and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-ThinItalic.woff b/src/Hosted/assets/media/fonts/Jost-ThinItalic.woff deleted file mode 100644 index fb117dda..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-ThinItalic.woff and /dev/null differ diff --git a/src/Hosted/assets/media/fonts/Jost-ThinItalic.woff2 b/src/Hosted/assets/media/fonts/Jost-ThinItalic.woff2 deleted file mode 100644 index 5924c414..00000000 Binary files a/src/Hosted/assets/media/fonts/Jost-ThinItalic.woff2 and /dev/null differ diff --git a/src/Hosted/assets/open-day.jpg b/src/Hosted/assets/open-day.jpg new file mode 100644 index 00000000..a04f6580 Binary files /dev/null and b/src/Hosted/assets/open-day.jpg differ diff --git a/src/Hosted/assets/open-position-1.jpg b/src/Hosted/assets/open-position-1.jpg new file mode 100644 index 00000000..90645729 Binary files /dev/null and b/src/Hosted/assets/open-position-1.jpg differ diff --git a/src/Hosted/assets/res_banner.jpg b/src/Hosted/assets/res_banner.jpg new file mode 100644 index 00000000..99631549 Binary files /dev/null and b/src/Hosted/assets/res_banner.jpg differ diff --git a/src/Hosted/assets/research-sign-dark.png b/src/Hosted/assets/research-sign-dark.png new file mode 100644 index 00000000..f8970a2d Binary files /dev/null and b/src/Hosted/assets/research-sign-dark.png differ diff --git a/src/Hosted/assets/skin.css b/src/Hosted/assets/skin.css index f885ed1e..ef7a6cd2 100644 --- a/src/Hosted/assets/skin.css +++ b/src/Hosted/assets/skin.css @@ -9,20 +9,6 @@ * */ -@font-face { - font-family: 'Jost'; - src: url('media/fonts/Jost-Book.woff2') format('woff2'), url('media/fonts/Jost-Book.woff') format('woff'); - font-weight: 400; - font-style: normal; -} - -@font-face { - font-family: 'Jost'; - src: url('media/fonts/Jost-Medium.woff2') format('woff2'), url('media/fonts/Jost-Medium.woff') format('woff'); - font-weight: 500; - font-style: normal; -} - /* # ANIMATIONS E GLOBAL @@ -944,14 +930,14 @@ ul .icon-list.icon-list-11 li { body, textarea { - font-family: 'Jost', sans-serif; + font-family: 'Roboto', sans-serif; line-height: 1.5em; font-size: 17px; font-weight: 400; } button, .input-text, .input-select, .input-textarea { - font-family: 'Jost', sans-serif; + font-family: sans-serif; font-size: 15px; } @@ -1180,7 +1166,7 @@ body > nav.menu-icon .menu-brand { .menu-cnt > ul > li > a, .dropdown > ul > li > a, .dropdown-submenu > ul > li > a, nav .col a { height: 50px; - line-height: 50px; + line-height: 52px; font-size: 18px; letter-spacing: .3px; } @@ -1307,7 +1293,7 @@ footer .menu-inner li { footer .menu-inner li > a { height: 32px; line-height: 32px; - font-size: 25px; + font-size: 22px; opacity: .7; } diff --git a/src/Hosted/assets/trainings-1.jpg b/src/Hosted/assets/trainings-1.jpg new file mode 100644 index 00000000..b4a50695 Binary files /dev/null and b/src/Hosted/assets/trainings-1.jpg differ diff --git a/src/Hosted/assets/trainings-2.jpg b/src/Hosted/assets/trainings-2.jpg new file mode 100644 index 00000000..5a4e6028 Binary files /dev/null and b/src/Hosted/assets/trainings-2.jpg differ diff --git a/src/Hosted/assets/trainings-3.jpg b/src/Hosted/assets/trainings-3.jpg new file mode 100644 index 00000000..b7eb5458 Binary files /dev/null and b/src/Hosted/assets/trainings-3.jpg differ diff --git a/src/Hosted/assets/trainings-4.jpg b/src/Hosted/assets/trainings-4.jpg new file mode 100644 index 00000000..dd8307c9 Binary files /dev/null and b/src/Hosted/assets/trainings-4.jpg differ diff --git a/src/Hosted/bloglist.html b/src/Hosted/bloglist.html index 737c3d5b..eb0a60d6 100644 --- a/src/Hosted/bloglist.html +++ b/src/Hosted/bloglist.html @@ -6,21 +6,23 @@ Blogs + + - - - - - - - - + + + + + + + +
-