Просмотр исходного кода

Merge pull request #66 from sharelatex/pr-ol-beta-theme

Overleaf beta theme & dashboard styling
Paulo Jorge Reis 9 лет назад
Родитель
Сommit
0453aa60fe
24 измененных файлов с 545 добавлено и 151 удалено
  1. 18 5
      services/web/Gruntfile.coffee
  2. 1 0
      services/web/app/coffee/Features/StaticPages/StaticPagesRouter.coffee
  3. 2 2
      services/web/app/views/layout/footer.pug
  4. 3 3
      services/web/app/views/layout/navbar.pug
  5. 6 6
      services/web/app/views/project/list.pug
  6. 3 0
      services/web/app/views/project/list/project-list.pug
  7. 2 2
      services/web/app/views/project/list/side-bar.pug
  8. 0 23
      services/web/npm-shrinkwrap.json
  9. 5 15
      services/web/public/coffee/main/project-list/project-list.coffee
  10. 0 0
      services/web/public/img/ol-brand/overleaf-white.svg
  11. 0 0
      services/web/public/img/ol-brand/overleaf.svg
  12. 1 0
      services/web/public/stylesheets/app/editor/review-panel.less
  13. 66 0
      services/web/public/stylesheets/app/ol-style-guide.less
  14. 122 48
      services/web/public/stylesheets/app/project-list.less
  15. 6 6
      services/web/public/stylesheets/components/buttons.less
  16. 2 2
      services/web/public/stylesheets/components/card.less
  17. 22 1
      services/web/public/stylesheets/components/footer.less
  18. 21 17
      services/web/public/stylesheets/components/navbar.less
  19. 3 3
      services/web/public/stylesheets/components/progress-bars.less
  20. 92 5
      services/web/public/stylesheets/core/_common-variables.less
  21. 158 9
      services/web/public/stylesheets/core/ol-variables.less
  22. 10 3
      services/web/public/stylesheets/core/scaffolding.less
  23. 1 1
      services/web/public/stylesheets/core/type.less
  24. 1 0
      services/web/public/stylesheets/ol-style.less

+ 18 - 5
services/web/Gruntfile.coffee

@@ -30,8 +30,10 @@ module.exports = (grunt) ->
 		exec:
 			run:
 				command:"node app.js | ./node_modules/logger-sharelatex/node_modules/bunyan/bin/bunyan --color"
-			cssmin:
-				command:"node_modules/clean-css/bin/cleancss --s0 -o public/stylesheets/style.css public/stylesheets/style.css"
+			cssmin_sl:
+				command:"node_modules/clean-css/bin/cleancss --s0 --source-map -o public/stylesheets/style.css public/stylesheets/style.css"
+			cssmin_ol:
+				command:"node_modules/clean-css/bin/cleancss --s0 --source-map -o public/stylesheets/ol-style.css public/stylesheets/ol-style.css"
 
 		forever:
 			app:
@@ -143,20 +145,31 @@ module.exports = (grunt) ->
 
 		less:
 			app:
+				options:
+					sourceMap: true
+					sourceMapFilename: "public/stylesheets/style.css.map"
+					sourceMapBasepath: "public/stylesheets"
 				files:
 					"public/stylesheets/style.css": "public/stylesheets/style.less"
 			ol:
+				options:
+					sourceMap: true
+					sourceMapFilename: "public/stylesheets/ol-style.css.map"
+					sourceMapBasepath: "public/stylesheets"
 				files:
 					"public/stylesheets/ol-style.css": "public/stylesheets/ol-style.less"
 
 		postcss:
 			options:
-				map: true,
+				map: 
+					prev: "public/stylesheets/"
+					inline: false
+					sourcesContent: true
 				processors: [
 					require('autoprefixer')({browsers: [ 'last 2 versions', 'ie >= 10' ]})
 				]
 			dist:
-				src: 'public/stylesheets/style.css'
+				src: [ "public/stylesheets/style.css", "public/stylesheets/ol-style.css" ]
 
 		env:
 			run:
@@ -390,7 +403,7 @@ module.exports = (grunt) ->
 	grunt.registerTask 'compile:server', 'Compile the server side coffee script', ['clean:app', 'coffee:app', 'coffee:app_dir', 'compile:modules:server']
 	grunt.registerTask 'compile:client', 'Compile the client side coffee script', ['coffee:client', 'coffee:sharejs', 'wrap_sharejs', "compile:modules:client", 'compile:modules:inject_clientside_includes']
 	grunt.registerTask 'compile:css', 'Compile the less files to css', ['less', 'postcss:dist']
-	grunt.registerTask 'compile:minify', 'Concat and minify the client side js', ['requirejs', "file_append", "exec:cssmin",]
+	grunt.registerTask 'compile:minify', 'Concat and minify the client side js and css', ['requirejs', "file_append", "exec:cssmin_sl", "exec:cssmin_ol"]
 	grunt.registerTask 'compile:unit_tests', 'Compile the unit tests', ['clean:unit_tests', 'coffee:unit_tests']
 	grunt.registerTask 'compile:acceptance_tests', 'Compile the acceptance tests', ['clean:acceptance_tests', 'coffee:acceptance_tests']
 	grunt.registerTask 'compile:smoke_tests', 'Compile the smoke tests', ['coffee:smoke_tests']

+ 1 - 0
services/web/app/coffee/Features/StaticPages/StaticPagesRouter.coffee

@@ -14,6 +14,7 @@ module.exports =
 		webRouter.get '/privacy_policy', HomeController.externalPage("privacy", "Privacy Policy")
 		webRouter.get '/planned_maintenance', HomeController.externalPage("planned_maintenance", "Planned Maintenance")
 		webRouter.get '/style', HomeController.externalPage("style_guide", "Style Guide")
+		webRouter.get '/ol-style', HomeController.externalPage("ol_style_guide", "Overleaf Style Guide")
 		webRouter.get '/jobs', HomeController.externalPage("jobs", "Jobs")
 
 		webRouter.get '/track-changes-and-comments-in-latex', HomeController.externalPage("review-features-page", "Review features")

+ 2 - 2
services/web/app/views/layout/footer.pug

@@ -1,7 +1,7 @@
 
 
 footer.site-footer
-	.container
+	.site-footer-content
 		.row
 			ul.col-md-9
 				
@@ -38,6 +38,6 @@ footer.site-footer
 				each item in nav.right_footer
 					li
 						if item.url
-							a(href=item.url, class=item.class) !{item.text}
+							a(href=item.url, class=item.class, aria-label=item.label) !{item.text}
 						else
 							| !{item.text}

+ 3 - 3
services/web/app/views/layout/navbar.pug

@@ -4,11 +4,11 @@ nav.navbar.navbar-default
 			button.navbar-toggle(ng-init="navCollapsed = true", ng-click="navCollapsed = !navCollapsed", ng-class="{active: !navCollapsed}")
 				i.fa.fa-bars
 			if settings.nav.custom_logo
-				a(href='/', style='background-image:url("'+settings.nav.custom_logo+'")').navbar-brand
+				a(href='/', aria-label=settings.appName, style='background-image:url("'+settings.nav.custom_logo+'")').navbar-brand
 			else if (nav.title)
-				a(href='/').navbar-title #{nav.title}
+				a(href='/', aria-label=settings.appName).navbar-title #{nav.title}
 			else
-				a(href='/').navbar-brand
+				a(href='/', aria-label=settings.appName).navbar-brand
 
 		.navbar-collapse.collapse(collapse="navCollapsed")
 

+ 6 - 6
services/web/app/views/project/list.pug

@@ -16,7 +16,7 @@ block content
 		};
 
 	.content.content-alt.project-list-page(ng-controller="ProjectPageController")
-		.container
+		.project-list-content
 			.announcements(
 				ng-controller="AnnouncementsController"
 				ng-class="{ 'announcements-open': ui.isOpen }"
@@ -57,16 +57,16 @@ block content
 								ng-click="showAll();"
 							) Show all
 
-			.row(ng-cloak)
-				span(ng-if="projects.length > 0")
-					aside.col-md-2.col-xs-3
+			.row.project-list-row(ng-cloak)
+				.project-list-container(ng-if="projects.length > 0")
+					aside.project-list-sidebar.col-md-2.col-xs-3
 						include ./list/side-bar
 
-					.col-md-10.col-xs-9
+					.project-list-main.col-md-10.col-xs-9
 						include ./list/notifications
 						include ./list/project-list
 				
-				span(ng-if="projects.length === 0")
+				.project-list-empty(ng-if="projects.length === 0")
 					.col-md-offset-2.col-md-8.col-md-offset-2.col-xs-8
 						include ./list/empty-project-list
 

+ 3 - 0
services/web/app/views/project/list/project-list.pug

@@ -7,6 +7,7 @@
 			.form-group.has-feedback.has-feedback-left.col-md-7.col-xs-12
 				input.form-control.col-md-7.col-xs-12(
 					placeholder=translate('search_projects')+"…",
+					aria-label=translate('search_projects')+"…",
 					autofocus='autofocus',
 					ng-model="searchText.value",
 					focus-on='search:clear',
@@ -127,6 +128,7 @@
 							input.select-all(
 								select-all,
 								type="checkbox"
+								aria-label=translate('select_all_projects')
 							)
 							span.header.clickable(ng-click="changePredicate('name')") #{translate("title")}
 								i.tablesort.fa(ng-class="getSortIconClass('name')")
@@ -147,6 +149,7 @@
 								type="checkbox",
 								ng-model="project.selected"
 								stop-propagation="click"
+								aria-label=translate('select_project') + " '{{ project.name }}'"
 							)
 							span
 								a.projectName(

+ 2 - 2
services/web/app/views/project/list/side-bar.pug

@@ -1,5 +1,5 @@
 .dropdown(dropdown)
-	a.btn.btn-primary.dropdown-toggle(
+	a.btn.btn-primary.sidebar-new-proj-btn.dropdown-toggle(
 		href="#",
 		data-toggle="dropdown",
 		dropdown-toggle
@@ -45,7 +45,7 @@
 			a(href) #{translate("shared_with_you")}
 		li(ng-class="{active: (filter == 'archived')}", ng-click="filterProjects('archived')")
 			a(href) #{translate("deleted_projects")}
-		li
+		li.separator
 			h2 #{translate("folders")}
 		li.tag(
 			ng-repeat="tag in tags | orderBy:'name'",

+ 0 - 23
services/web/npm-shrinkwrap.json

@@ -6773,29 +6773,6 @@
         }
       }
     },
-    "translations-sharelatex": {
-      "version": "git+https://github.com/sharelatex/translations-sharelatex.git#12d5cefc591bcc0b4e54b5ce9acfbd980208b9e1",
-      "dev": true,
-      "requires": {
-        "async": "2.5.0",
-        "coffee-script": "1.12.4",
-        "i18next": "1.7.10",
-        "onesky": "0.1.6",
-        "sanitize-html": "1.14.1",
-        "underscore": "1.6.0"
-      },
-      "dependencies": {
-        "async": {
-          "version": "2.5.0",
-          "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
-          "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==",
-          "dev": true,
-          "requires": {
-            "lodash": "4.17.4"
-          }
-        }
-      }
-    },
     "tsscmp": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz",

+ 5 - 15
services/web/public/coffee/main/project-list/project-list.coffee

@@ -26,22 +26,12 @@ define [
 		storedUIOpts = JSON.parse(localStorage("project_list"))
 
 		recalculateProjectListHeight = () ->
-			topOffset = $(".project-list-card")?.offset()?.top
-			bottomOffset = $("footer").outerHeight() + 25
-			sideBarHeight = $("aside").height() - 56
-			# When footer is visible and page doesn't need to scroll we just make it
-			# span between header and footer
-			height = $window.innerHeight - topOffset - bottomOffset
-			
-			# When page is small enough that this pushes the project list smaller than
-			# the side bar, then the window going to have to scroll to take into account the
-			# footer. So we now start to track to the bottom of the window, with a 25px padding
-			# since the footer is hidden below the fold. Don't ever get bigger than the sidebar
-			# though since that's what triggered this happening in the first place.
-			if height < sideBarHeight
-				height = Math.min(sideBarHeight, $window.innerHeight - topOffset - 25)
+			$projListCard = $(".project-list-card")
+			topOffset = $projListCard.offset()?.top
+			cardPadding = $projListCard.outerHeight() - $projListCard.height()
+			bottomOffset = $("footer").outerHeight()
+			height = $window.innerHeight - topOffset - bottomOffset - cardPadding
 			$scope.projectListHeight = height
-		
 
 		angular.element($window).bind "resize", () ->
 			recalculateProjectListHeight()

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
services/web/public/img/ol-brand/overleaf-white.svg


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
services/web/public/img/ol-brand/overleaf.svg


+ 1 - 0
services/web/public/stylesheets/app/editor/review-panel.less

@@ -941,6 +941,7 @@
 	justify-content: center;
 	border-radius: 3px;
 	box-shadow: 0 0 20px 10px rgba(0, 0, 0, .3);
+	z-index: 1;
 
 	&::before {
 		content: '';

+ 66 - 0
services/web/public/stylesheets/app/ol-style-guide.less

@@ -0,0 +1,66 @@
+.renderColorSwatchClasses(@colorName) {
+	@colorVal: @@colorName;
+	@colorValRed: red(@colorVal);
+	@colorValGreen: green(@colorVal);
+	@colorValBlue: blue(@colorVal);
+	@colorValAsRGB: 'rgb(@{colorValRed}, @{colorValGreen}, @{colorValBlue})';
+
+	&.@{colorName} {
+		.color-swatch {
+			background-color: @colorVal;
+		}
+		.color-less-var::before {
+			content: '@@{colorName}';
+		}
+		.color-hex-val::before {
+			content: '@{colorVal}';
+		}
+		.color-rgb-val::before {
+			font-size: 10px;
+			content: '@{colorValAsRGB}';
+		}
+	}
+}
+
+.color-row {
+	display: flex;
+	justify-content: space-between;
+}
+
+.color-box {
+	background: white;
+	margin: 10px 4px;
+	border-radius: 4px;
+	width: 16.666%;
+	.renderColorSwatchClasses(ol-blue-gray-1);
+	.renderColorSwatchClasses(ol-blue-gray-2);
+	.renderColorSwatchClasses(ol-blue-gray-3);
+	.renderColorSwatchClasses(ol-blue-gray-4);
+	.renderColorSwatchClasses(ol-blue-gray-5);
+	.renderColorSwatchClasses(ol-blue-gray-6);
+	.renderColorSwatchClasses(ol-green);
+	.renderColorSwatchClasses(ol-dark-green);
+	.renderColorSwatchClasses(ol-blue);
+	.renderColorSwatchClasses(ol-dark-blue);
+	.renderColorSwatchClasses(ol-red);
+	.renderColorSwatchClasses(ol-dark-red);
+}
+
+.color-swatch {
+	height: 100px;
+	width: 100px;
+	margin: 10px auto;
+	border-radius: 4px;
+}
+
+.color-label {
+	display: flex;
+	flex-direction: column;
+	margin: 0 3px 10px;
+}
+
+.color-label pre {
+	font-size: 12px;
+	line-height: 1.8em;
+	margin: 0 auto;
+}

+ 122 - 48
services/web/public/stylesheets/app/project-list.less

@@ -18,9 +18,56 @@
 }
 
 .project-list-page {
-	position: relative;
+	position: absolute;
+	top: @header-height;
+	bottom: @footer-height;
+	padding-top: 0;
+	padding-bottom: 0;
+	width: 100%;
+	overflow-x: hidden;
+	overflow-y: auto;
 }
 
+.project-list-content when (@is-overleaf) {
+	.container-fluid;
+	margin: 0;
+	height: 100%;
+}
+
+.project-list-content when (@is-overleaf = false) {
+	.container;
+}
+
+.sidebar-new-proj-btn when (@is-overleaf) {
+	.btn-block;
+}
+
+	.project-list-row when (@is-overleaf) {
+		height: 100%;
+	}
+		.project-list-container when (@is-overleaf) {
+			height: 100%;
+		}
+		.project-list-sidebar {
+			background-color: @sidebar-bg;
+			padding-top: @content-margin-vertical;
+			padding-bottom: @content-margin-vertical;
+		} 
+
+		.project-list-sidebar when (@is-overleaf) {
+			height: 100%;
+			overflow-x: hidden;
+			overflow-y: auto;
+			-ms-overflow-style: -ms-autohiding-scrollbar;
+		}
+
+		.project-list-main {
+			padding-top: @content-margin-vertical;
+			padding-bottom: @content-margin-vertical;
+			height: 100%;
+			overflow: hidden;
+		}
+
 .project-header {
 	.btn-group > .btn {
 		padding-left: @line-height-base / 2;
@@ -48,6 +95,9 @@
 	}
 	p {
 		margin-bottom: @line-height-computed / 4;
+		&.small {
+			color: @sidebar-color;
+		}
 	}
 }
 
@@ -76,27 +126,38 @@
 }
 
 ul.folders-menu {
-	margin: 0;
+	margin: @folders-menu-margin;
 	.subdued {
 		color: @gray-light;
 	}
 	> li {
 		cursor: pointer;
-		line-height: 1.8;
 		position: relative;
 		> a {
+			display: block;
+			color: @sidebar-link-color;
+			padding: @folders-menu-item-v-padding @folders-menu-item-h-padding;
+			border-bottom: solid 1px transparent;
+			&:hover {
+				background-color: @sidebar-hover-bg;
+				text-decoration: @sidebar-hover-text-decoration;
+			}
+			&:focus {
+				text-decoration: none;
+			}
+		}
+		> a when (@is-overleaf = false) {
 			font-size: 0.9rem;
-			color: #333;
-			padding: (@line-height-computed / 4);
-			display: inline-block;
-			line-height: 1.2;
+		}
+		&.separator {
+			padding: @folders-menu-item-v-padding @folders-menu-item-h-padding;
+			cursor: auto;
 		}
 	}
 	> li.active {
-		//border-right: 4px solid @red;
-		background-color: @link-color;
-		border-radius: @border-radius-small;
+		border-radius: @sidebar-active-border-radius;
 		> a {
+			background-color: @sidebar-active-bg;
 			font-weight: 700;
 			color: white;
 			.subdued {
@@ -108,10 +169,13 @@ ul.folders-menu {
 		color: @gray;
 	}
 	h2 {
-		margin-top: @line-height-computed / 2;
-		margin-bottom: @line-height-computed / 4;
-		font-size: @font-size-base;
-		font-weight: 500;
+		margin-top: @folders-title-margin-top;
+		margin-bottom: @folders-title-margin-bottom;
+		font-size: @folders-title-font-size;
+		color: @folders-title-color;
+		text-transform: @folders-title-text-transform;
+		padding: @folders-title-padding;
+		font-weight: @folders-title-font-weight;
 		font-family: @font-family-sans-serif;
 	}
 	> li.tag {
@@ -120,7 +184,7 @@ ul.folders-menu {
 				color: white;
 				border-color: white;
 				&:hover {
-					background-color: darken(@brand-primary, 10%);
+					background-color: @folders-tag-menu-active-hover;
 				}
 			}
 		}
@@ -128,7 +192,7 @@ ul.folders-menu {
 			font-style: italic;
 			margin-bottom: @line-height-computed / 4;
 			a {
-				line-height: 1.7;
+				line-height: @folders-untagged-line-height;
 				&:hover,
 				&:focus {
 					text-decoration: none;
@@ -140,7 +204,7 @@ ul.folders-menu {
 		}
 		&:hover {
 			&:not(.active) {
-				background-color: darken(@gray-lightest, 2%);
+				background-color: @folders-tag-hover;
 			}
 			.tag-menu {
 				display: block
@@ -148,30 +212,23 @@ ul.folders-menu {
 		}
 		&:not(.active) {
 			.tag-menu > a:hover {
-				background-color: @gray-light;
+				background-color: @folders-tag-menu-hover;
 			}
 		}
 		a.tag-name {
-			padding: 2px (@line-height-computed / 4);
-			margin-right: 18px;
-			display: inline-block;
+			padding: @folders-tag-padding;
+			display: @folders-tag-display;
 			position: relative;
-			i {
-				position: absolute;
-				top: 5px;
-				left: 6px;
-			}
 			span.name {
-				display: inline-block;
-				padding-left: 22px;
-				line-height: 1.4;
+				padding-left: 0.5em;
+				line-height: @folders-tag-line-height;
 			}
 		}
 		.tag-menu {
 			> a {
-				border: 1px solid @gray;
+				border: 1px solid @folders-tag-border-color;
 				border-radius: @border-radius-small;
-				color: @text-color;
+				color: @folders-tag-menu-color;
 				display: block;
 				width: 16px;
 				height: 16px;
@@ -184,7 +241,8 @@ ul.folders-menu {
 			}
 			display: none;
 			position: absolute;
-			top: 6px;
+			top: 50%;
+			margin-top: -8px; // Half the element height.
 			right: 4px;
 			&.open {
 				display: block;
@@ -204,32 +262,34 @@ ul.structured-list {
 	margin: 0;
 	overflow: hidden;
 	overflow-y: auto;
+	-ms-overflow-style: -ms-autohiding-scrollbar;
 	li {
-		border-bottom: 1px solid @gray-lightest;
+		border-bottom: 1px solid @structured-list-border-color;
 		padding: (@line-height-computed / 4) 0;
-		&:first-child {
-			.header {
-				font-size: 1rem;
-			}
-		}
+		
 		&:last-child {
 			border-bottom: 0 none;
 		}
 		&:hover {
-			background-color: @gray-lightest;
+			background-color: @structured-list-hover-color;
 		}
-		&:first-child:hover {
-			background-color: white;
+		&:first-child {
+			border-bottom-color: @structured-header-border-color;
+			&:hover {
+				background-color: transparent;
+			}
 		}
 		a {
-			color: darken(@blue, 10%);
+			color: @structured-list-link-color;
 		}
-		.header {
-			text-transform: uppercase;
+		.header when (@is-overleaf = true) {
+			font-weight: 600;
 		}
-		.select-item, .select-all {
-			display: inline-block;
+
+		.header when (@is-overleaf = false) {
+			text-transform: uppercase;
 		}
+		
 		.select-item, .select-all {
 			position: absolute;
 			left: @line-height-computed;
@@ -245,17 +305,25 @@ ul.structured-list {
 	}
 }
 
+.project-list-card when (@is-overleaf) {
+	padding: 0 (@line-height-computed / 4);
+}
+
 ul.project-list {
 	li {
-		.last-modified, .owner {
+		.last-modified when (@is-overleaf = false) {
 			font-size: .8rem;
 		}
-		.owner {
+		.owner when (@is-overleaf = false) {
+			font-size: .8rem;
+		}
+		.owner when (@is-overleaf = false) {
 			margin-right: 0;
 		}
 		.projectName {
 			margin-right: @line-height-computed / 4;
 		}
+
 		.tag-label {
 			margin-left: @line-height-computed / 4;
 			position: relative;
@@ -267,6 +335,12 @@ ul.project-list {
 				display: inline-block;
 				padding-top: 0.3em;
 				color: #FFF;
+				border-radius: @tag-border-radius;
+				background-color: @tag-bg-color;
+				&:hover,
+				&:focus {
+					background-color: @tag-bg-hover-color;
+				}
 			}
 			.tag-label-name {
 				padding-right: 0.3em;

+ 6 - 6
services/web/public/stylesheets/components/buttons.less

@@ -14,10 +14,10 @@
   vertical-align: middle;
   cursor: pointer;
   background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
-  border: 1px solid transparent;
-  border-bottom: 2px solid transparent;
+  border: @btn-border-width solid transparent;
+  border-bottom: @btn-border-bottom-width solid transparent;
   white-space: nowrap;
-  .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);
+  .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);
   .user-select(none);
 
   &,
@@ -124,14 +124,14 @@
 
 .btn-lg {
   // line-height: ensure even-numbered height of button next to large input
-  .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
+  .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);
 }
 .btn-sm {
   // line-height: ensure proper height of button next to small input
-  .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
+  .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);
 }
 .btn-xs {
-  .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);
+  .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);
 }
 
 

+ 2 - 2
services/web/public/stylesheets/components/card.less

@@ -1,8 +1,8 @@
 .card {
   background-color: white;
   border-radius: @border-radius-base;
-  -webkit-box-shadow: 0 2px 4px rgba(0,0,0,0.1);
-  box-shadow: 0 2px 4px rgba(0,0,0,0.15);
+  -webkit-box-shadow: @card-box-shadow;
+  box-shadow: @card-box-shadow;
   padding: @line-height-computed;
   .page-header {
   	margin: 0 0 1.5625rem;

+ 22 - 1
services/web/public/stylesheets/components/footer.less

@@ -1,7 +1,13 @@
 footer.site-footer {
+	background-color: @footer-bg-color;
 	border-top: 1px solid @gray-lighter;
-	padding: 2em;
 	font-size: 0.9rem;
+	position: absolute;
+	bottom: 0;
+	width: 100%;
+	height: @footer-height;
+	line-height: @footer-height - 1; // Hack — in Chrome, using the full @footer-height would generate vertical scrolling
+		
 	ul {
 		list-style: none;
 		margin: 0px;
@@ -22,6 +28,21 @@ footer.site-footer {
 			vertical-align: text-bottom;
 		}
 	}
+
+	a {
+		color: @footer-link-color;
+		&:hover,
+		&:focus {
+			color: @footer-link-hover-color;
+		}
+	}
+}
+
+.site-footer-content when (@is-overleaf = true) {
+	.container-fluid;
+}
+.site-footer-content when (@is-overleaf = false) {
+	.container;
 }
 
 .sprite-icon-lang {

+ 21 - 17
services/web/public/stylesheets/components/navbar.less

@@ -174,9 +174,9 @@
     font-size: 20px;
     display: inline-block;
     margin-top: 2px;
-    color: #666;
+    color: @navbar-title-color;
     &:hover, &:active, &:focus {
-        color: #333;
+        color: @navbar-title-color-hover;
         text-decoration: none;
     }
 }
@@ -378,13 +378,17 @@
 .navbar-default {
   background-color: @navbar-default-bg;
   border-color: @navbar-default-border;
-  padding: 1rem 2rem;
-
+  padding: @navbar-default-padding;
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: @header-height;
+  
   .navbar-brand {
     position: absolute;
     top: 5px;
     bottom: 5px;
-    width: 180px;
+    width: @navbar-brand-width;
     padding: 0;
     background-image: @navbar-brand-image-url;
     background-size: contain;
@@ -400,11 +404,11 @@
     > li > a {
       color: @navbar-default-link-color;
       border: 2px solid transparent;
-      border-radius: @border-radius-base;
-      font-size: @font-size-base * .8;
-      font-weight: 700;
-      line-height: 1;
-      padding: 10px 10px 11px;
+      border-radius: @navbar-btn-border-radius;
+      font-size: @navbar-btn-font-size;
+      font-weight: @navbar-btn-font-weight;
+      line-height: @navbar-btn-line-height;
+      padding: @navbar-btn-padding;
 
       &:hover,
       &:focus {
@@ -432,15 +436,15 @@
 
     > li.subdued > a {
       border: 0;
-      color: @gray;
-      padding: 12px 12px 13px;
+      color: @navbar-subdued-color;
+      padding: @navbar-subdued-padding;
       margin-left: 0;
       &:hover {
-        color: @gray-dark;
-        background-color: @gray-lightest;
+        color: @navbar-subdued-hover-color;
+        background-color: @navbar-subdued-hover-bg;
       }
       &:focus {
-          color: @gray;
+          color: @navbar-subdued-color;
           background-color: transparent;
       }
     }
@@ -485,8 +489,8 @@
       &,
       &:hover,
       &:focus {
-        color: @gray-dark;
-        background-color: @gray-lightest;
+        color: @navbar-subdued-hover-color;
+        background-color: @navbar-subdued-hover-bg;
       }
     }
 

+ 3 - 3
services/web/public/stylesheets/components/progress-bars.less

@@ -29,8 +29,8 @@
   height: @line-height-computed;
   margin-bottom: @line-height-computed;
   background-color: @progress-bg;
-  border-radius: @border-radius-base;
-  border: 1px solid @progress-border-color;
+  border-radius: @progress-border-radius;
+  border: @progress-border-width solid @progress-border-color;
   .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
 }
 
@@ -44,7 +44,7 @@
   color: @progress-bar-color;
   text-align: center;
   background-color: @progress-bar-bg;
-  .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));
+  .box-shadow(@progress-bar-shadow);
   .transition(width .6s ease);
 }
 

+ 92 - 5
services/web/public/stylesheets/core/_common-variables.less

@@ -85,7 +85,6 @@
 @border-radius-base:        3px;
 @border-radius-large:       5px;
 @border-radius-small:       2px;
-
 //** Global color for active items (e.g., navs or dropdowns).
 @component-active-color:    #fff;
 //** Global background color for active items (e.g., navs or dropdowns).
@@ -789,10 +788,7 @@
 //** Horizontal offset for forms and lists.
 @component-offset-horizontal: 180px;
 
-@content-margin-top: @line-height-computed;
-@content-margin-top: @line-height-computed;
-
-// Custom
+@content-margin-vertical: @line-height-computed;
 
 @left-menu-width: 260px;
 @left-menu-animation-duration: 0.35s;
@@ -803,3 +799,94 @@
 @editor-dark-background-color: #333;
 @editor-dark-toolbar-border-color: #222;
 @editor-dark-highlight-color: #FFA03A;
+
+
+// Custom
+@is-overleaf   : false;
+@header-height : 68px;
+@footer-height : 50px;
+
+// Backgrounds
+@content-alt-bg-color: lighten(@gray-lightest, 2.5%);
+
+// Typography
+@text-small-color: @gray;
+
+// Navbar
+@navbar-title-color         : #666;
+@navbar-title-color-hover   : #333;
+@navbar-default-padding     : 1rem 2rem;
+@navbar-brand-width         : 180px;
+@navbar-btn-font-size       : @font-size-base * 0.8;
+@navbar-btn-border-radius   : @border-radius-base;
+@navbar-btn-font-weight     : 700;
+@navbar-btn-padding         : 10px 10px 11px;
+@navbar-btn-line-height     : 1;
+@navbar-subdued-padding     : 12px 12px 13px;
+@navbar-subdued-color       : @gray;
+@navbar-subdued-hover-bg    : @gray-lightest;
+@navbar-subdued-hover-color : @gray-dark;
+
+// Button colors and sizing
+@btn-border-radius-large : @border-radius-large;
+@btn-border-radius-base  : @border-radius-base;
+@btn-border-radius-small : @border-radius-small;
+@btn-border-width        : 1px;
+@btn-border-bottom-width : 2px; 
+
+// Cards
+@card-box-shadow: 0 2px 4px rgba(0,0,0,0.15);
+
+// Project table
+@structured-list-link-color     : darken(@blue, 10%);
+@structured-header-border-color : @gray-lightest;
+@structured-list-border-color   : @gray-lightest;
+@structured-list-hover-color    : @gray-lightest;
+@structured-list-line-height    : @line-height-base;
+
+// Sidebar
+@sidebar-bg                    : transparent;
+@sidebar-color                 : @gray;
+@sidebar-link-color            : #333;
+@sidebar-active-border-radius  : @border-radius-small;
+@sidebar-active-bg             : @link-color;
+@sidebar-hover-bg              : transparent;
+@sidebar-hover-text-decoration : underline;
+
+@folders-menu-margin           : 0;
+@folders-menu-line-height      : 1.2;
+@folders-menu-item-v-padding   : (@line-height-computed / 4);
+@folders-menu-item-h-padding   : (@line-height-computed / 4);
+@folders-title-padding         : 0;
+@folders-title-margin-top      : (@line-height-computed / 2);
+@folders-title-margin-bottom   : (@line-height-computed / 4);
+@folders-title-font-size       : @font-size-base;
+@folders-title-font-weight     : 500;
+@folders-title-line-height     : @headings-line-height;
+@folders-title-color           : inherit;
+@folders-title-text-transform  : none;
+@folders-tag-padding           : 2px 20px 2px @folders-menu-item-h-padding;
+@folders-tag-line-height       : 1.8;
+@folders-tag-display           : block;
+@folders-tag-menu-color        : @gray;
+@folders-tag-hover             : darken(@gray-lightest, 2%);
+@folders-tag-border-color      : @text-color;
+@folders-tag-menu-active-hover : darken(@brand-primary, 10%);
+@folders-tag-menu-hover        : @gray-light;
+@folders-untagged-line-height  : 1.7;
+
+// Progress bars
+@progress-border-radius : @border-radius-base;
+@progress-border-width  : 1px;
+@progress-bar-shadow    : inset 0 -1px 0 rgba(0,0,0,.15);
+
+// Footer
+@footer-link-color       : @link-color;
+@footer-link-hover-color : @link-hover-color;
+@footer-bg-color         : transparent;
+@footer-padding          : 2em;
+
+// Tags
+@tag-border-radius  : 0.25em;
+@tag-bg-color       : @label-default-bg;
+@tag-bg-hover-color : darken(@label-default-bg, 10%);

+ 158 - 9
services/web/public/stylesheets/core/ol-variables.less

@@ -1,11 +1,164 @@
-@ol-green:      #4A9F48;
-@ol-dark-green: #1C5B26;
+@import "./_common-variables.less";
+
+@is-overleaf: true;
+@header-height: 68px;
+@footer-height: 50px;
+
+// Styleguide colors
+@ol-blue-gray-1 : #E4E8EE;
+@ol-blue-gray-2 : #9DA7B7;
+@ol-blue-gray-3 : #5D6879;
+@ol-blue-gray-4 : #485973;
+@ol-blue-gray-5 : #2C3645;
+@ol-blue-gray-6 : #1E2530;
+
+@ol-green       : #4F9C45;
+@ol-dark-green  : #1C5B26;
+@ol-blue        : #4B7FD1;
+@ol-dark-blue   : #2857A1;
+@ol-red         : #C9453E;
+@ol-dark-red    : #A6312B;
+
+@ol-type-color  : @ol-blue-gray-3;
+
+// Navbar customization
+@navbar-title-color       : @ol-blue-gray-1;
+@navbar-title-color-hover : @ol-blue-gray-2;
+@navbar-brand-width       : 130px;
+@navbar-default-color     : #FFF;
+@navbar-default-bg        : @ol-blue-gray-6;
+@navbar-default-border    : transparent;
+@navbar-brand-image-url   : url(/img/ol-brand/overleaf-white.svg);
+
+// Backgrounds
+@body-bg                : #FFF;
+@content-alt-bg-color   : @ol-blue-gray-1;
+
+// Typography
+@text-small-color       : @ol-type-color;
+@text-color             : @ol-type-color;
+@link-color             : @ol-blue;
+@link-hover-color       : @ol-dark-blue;
+
+// Button colors and sizing
+@btn-border-width        : 0;
+@btn-border-bottom-width : 0;
+
+@btn-border-radius-large : 9999px;
+@btn-border-radius-base  : 9999px;
+@btn-border-radius-small : 9999px;
+
+@btn-default-color       : #FFF;
+@btn-default-bg          : @ol-blue-gray-4;
+@btn-default-border      : transparent;
+
+@btn-primary-color       : #FFF;
+@btn-primary-bg          : @ol-green;
+@btn-primary-border      : transparent;
+
+@btn-success-color       : #FFF;
+@btn-success-bg          : @ol-green;
+@btn-success-border      : transparent;
+
+@btn-info-color          : #FFF;
+@btn-info-bg             : @ol-blue;
+@btn-info-border         : transparent;
+
+// Tags
+@tag-border-radius       : 9999px;
+@tag-bg-color            : @ol-green;
+@tag-bg-hover-color      : @ol-dark-green;
+
+// Navbar
+@navbar-default-padding           : (@grid-gutter-width / 2) 0;
+@navbar-default-link-color        : #FFF;
+@navbar-default-link-hover-bg     : @ol-green;
+@navbar-default-link-active-bg    : @ol-green;
+@navbar-default-link-hover-color  : @ol-green;
+@navbar-btn-font-size             : @font-size-base;
+@navbar-btn-border-radius         : @btn-border-radius-base;
+@navbar-btn-font-weight           : 400;
+@navbar-btn-padding               : (@padding-base-vertical - 1) @padding-base-horizontal @padding-base-vertical;
+@navbar-btn-line-height           : @line-height-base;
+
+@navbar-subdued-color             : #FFF;
+@navbar-subdued-padding           : (@padding-base-vertical + 1) (@padding-base-horizontal + 1) (@padding-base-vertical + 2);
+@navbar-subdued-hover-bg          : #FFF;
+@navbar-subdued-hover-color       : @ol-green;
+
+// Forms
+@input-color                      : @ol-blue-gray-3;
+@input-border-radius              : unit(@line-height-base, em);
+@input-height-base                : @line-height-computed + (@padding-base-vertical * 2) - 1;
+// TODO Warning color-orange?
+@btn-warning-color                : #FFF;
+@btn-warning-bg                   : @ol-red;
+@btn-warning-border               : transparent;
+
+@btn-danger-color                 : #FFF;
+@btn-danger-bg                    : @ol-red;
+@btn-danger-border                : transparent;
+
+// Cards
+@card-box-shadow                  : none;
+
+// Sidebar
+@sidebar-bg                     : @ol-blue-gray-5;
+@sidebar-color                  : @ol-blue-gray-2;
+@sidebar-link-color             : #FFF;
+@sidebar-active-border-radius   : 0;
+@sidebar-active-bg              : @ol-blue-gray-6;
+@sidebar-hover-bg               : @ol-blue-gray-4;
+@sidebar-hover-text-decoration  : none;
+
+@folders-menu-margin            : 0 -(@grid-gutter-width / 2);
+@folders-menu-line-height       : @structured-list-line-height;
+@folders-menu-item-v-padding    : (@line-height-computed / 4);
+@folders-menu-item-h-padding    : (@grid-gutter-width / 2);
+@folders-title-padding          : @folders-menu-item-v-padding 0;
+@folders-title-margin-top       : 0;
+@folders-title-margin-bottom    : 0;
+@folders-title-font-weight      : normal;
+@folders-title-font-size        : @font-size-small;
+@folders-title-color            : @ol-blue-gray-2;
+@folders-title-text-transform   : uppercase;
+@folders-tag-display            : block;
+@folders-tag-line-height        : 1.4;
+@folders-tag-padding            : @folders-menu-item-v-padding 20px @folders-menu-item-v-padding @folders-menu-item-h-padding;
+@folders-tag-menu-color         : #FFF;
+@folders-tag-hover              : @sidebar-hover-bg;
+@folders-tag-border-color       : @folders-tag-menu-color;
+@folders-tag-menu-hover         : rgba(0, 0, 0, .1);
+@folders-tag-menu-active-hover  : rgba(0, 0, 0, .1);
+@folders-untagged-line-height   : @folders-menu-line-height;
+
+// Project table
+@structured-list-line-height    : 2.5;
+@structured-list-link-color     : @ol-blue;
+@structured-header-border-color : shade(@ol-blue-gray-1, 5%);
+@structured-list-border-color   : @ol-blue-gray-1;
+@structured-list-hover-color    : lighten(@ol-blue-gray-1, 5%);
+
+
+// Progress bars
+@progress-border-radius         : @line-height-computed;
+@progress-border-width          : 0;
+@progress-bar-bg                : @ol-blue-gray-4;
+@progress-bar-success-bg        : @ol-green;
+@progress-bar-warning-bg        : @brand-warning;
+@progress-bar-danger-bg         : @ol-red;
+@progress-bar-info-bg           : @ol-blue;
+@progress-bar-shadow            : none;
+
+// Footer
+@footer-bg-color                : #FFF;
+@footer-link-color              : @ol-green;
+@footer-link-hover-color        : @ol-dark-green;
+@footer-padding                 : 2em 0;
 
 //== Colors
 //
 //## Gray and brand colors for use across Bootstrap.
-
-
 @gray-darker:           #252525;
 @gray-dark:             #505050;
 @gray:                  #7a7a7a;
@@ -28,10 +181,6 @@
 @brand-warning:         @orange;
 @brand-danger:          #E03A06;
 
-@navbar-brand-image-url: url(/img/ol-brand/logo-horizontal.png);
-
 @editor-loading-logo-padding-top: 115.44%;
 @editor-loading-logo-background-url: url(/img/ol-brand/overleaf-o-grey.svg);
-@editor-loading-logo-foreground-url: url(/img/ol-brand/overleaf-o.svg);
-
-@import "./_common-variables.less";
+@editor-loading-logo-foreground-url: url(/img/ol-brand/overleaf-o.svg);

+ 10 - 3
services/web/public/stylesheets/core/scaffolding.less

@@ -29,6 +29,13 @@ body {
   line-height: @line-height-base;
   color: @text-color;
   background-color: @body-bg;
+  min-height: 100vh;
+  position: relative;
+  padding-top: @header-height;
+  padding-bottom: @footer-height;
+  & > .content {
+    min-height: calc(~"100vh -" (@header-height + @footer-height));
+  }
 }
 
 // Reset fonts for relevant elements
@@ -137,12 +144,12 @@ hr {
 }
 
 .content {
-  padding-top: @content-margin-top;
-  padding-bottom: @content-margin-top;
+  padding-top: @content-margin-vertical;
+  padding-bottom: @content-margin-vertical;
 }
 
 .content-alt {
-  background-color: lighten(@gray-lightest, 2.5%);
+  background-color: @content-alt-bg-color;
 }
 
 .row-spaced {

+ 1 - 1
services/web/public/stylesheets/core/type.less

@@ -81,7 +81,7 @@ p {
 
 // Ex: 14px base font * 85% = about 12px
 small,
-.small  { font-size: 90%; color: @gray }
+.small  { font-size: 90%; color: @text-small-color; }
 
 // Undo browser default styling
 cite    { font-style: normal; }

+ 1 - 0
services/web/public/stylesheets/ol-style.less

@@ -1,3 +1,4 @@
 // Core variables and mixins
 @import "core/ol-variables.less";
+@import "app/ol-style-guide.less";
 @import "_style_includes.less";

Некоторые файлы не были показаны из-за большого количества измененных файлов