├── .gitignore ├── README.md ├── css ├── grid12.css ├── normalize.css └── style.css ├── data └── data.json ├── fonts ├── Montserrat-Bold.otf ├── Montserrat-Light.otf ├── Montserrat-Regular.otf └── Montserrat-SemiBold.otf ├── img ├── about-done-img.png ├── about-img.jpeg ├── home-bg1.jpg ├── home-bg2.jpg ├── home-bg3.jpg ├── logo.png ├── news-img1.jpeg ├── options-icon1.png ├── options-icon2.png ├── options-icon3.png ├── options-icon4.png ├── service-img1.jpg ├── service-img2.jpg ├── social-hover-icon1.png ├── social-hover-icon2.png ├── social-hover-icon3.png ├── social-hover-icon4.png ├── social-icon1.png ├── social-icon2.png ├── social-icon3.png ├── social-icon4.png ├── team_member1.jpg ├── work-img1.jpg ├── work-img2.jpg ├── work-img3.jpg ├── work-img4.jpg ├── work-img5.jpg └── work-img6.jpg ├── index.html ├── js ├── build │ └── bundle.js └── src │ ├── actions │ ├── aboutActions.js │ ├── contactFormActions.js │ ├── feedbackActions.js │ ├── newsActions.js │ ├── portfolioActions.js │ ├── sliderActions.js │ └── teamFactsActions.js │ ├── components │ ├── aboutSection │ │ ├── biographyBlock.jsx │ │ ├── historyBlock.jsx │ │ └── skillsBlock.jsx │ ├── feedbackItem.jsx │ ├── newsItem.jsx │ ├── portfolioItem.jsx │ ├── serviceSection │ │ └── ServiceItems.jsx │ ├── slider │ │ ├── sliderItem1.jsx │ │ ├── sliderItem2.jsx │ │ └── sliderItem3.jsx │ ├── teamFactsItem.jsx │ └── teamMember.jsx │ ├── containers │ ├── aboutApp.jsx │ ├── contactFormApp.jsx │ ├── feedbackApp.jsx │ ├── newsApp.jsx │ ├── portfolioApp.jsx │ ├── sliderApp.jsx │ └── teamFactsApp.jsx │ ├── data │ └── data.json │ ├── main.jsx │ ├── main │ ├── AboutSection.jsx │ ├── ContactSection.jsx │ ├── FeedbackSection.jsx │ ├── Footer.jsx │ ├── Header.jsx │ ├── HomeSection.jsx │ ├── NewsSection.jsx │ ├── NewsView.jsx │ ├── ServiceSection.jsx │ ├── TeamSection.jsx │ └── WorkSection.jsx │ └── reducers │ ├── aboutReducer.js │ ├── contactFormReducer.js │ ├── feedbackReducer.js │ ├── newsReducer.js │ ├── portfolioReducer.js │ ├── sliderReducer.js │ └── teamFactsReducer.js ├── package.json ├── task ├── data.json ├── images │ ├── 000.jpg │ ├── 001.jpg │ ├── 002.jpg │ ├── 003.jpg │ ├── 004.jpg │ ├── 005.jpg │ ├── 006.jpg │ ├── 007.jpg │ ├── 008.jpg │ ├── 009.jpg │ └── 010.jpg ├── requirements.md └── template.psd └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea/ 3 | npm-debug.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Project - ReactJS - landing page 2 | It's one-week project of Ignite ReactJS courses block. All dynamic of landing page (theHam psd template) realized at ReactJS + Redux. Bootstrap 3 grid system used to make page responsive. 3 | 4 | * Link to result: https://ozadev.github.io/project-react-landing 5 | * Link to psd template: https://github.com/ozadev/project-react-landing/tree/master/task/template.psd 6 | * Link to course material: https://github.com/ozadev/ignite/tree/master/ReactJS 7 | 8 | ## Задача 9 | * Создание сайта-портфолио по предоставленному psd макету. 10 | 11 | ## Общие требования к сайту 12 | * Корректное отображение сайта на следующих разрешениях экрана: 320px, 687px, 992px, 1200 px 13 | * Поддержка браузеров: последние версии Chrome, Firefox, Safarі, Opera, MS Edge. 14 | * Для реализации функционала сайта используйте ReactJS. 15 | 16 | ## Структура сайта: 17 | 18 | ### Header 19 | ![](./task/images/000.jpg) 20 | 21 | * Меню дожно быть зафиксировано в верхней части экрана, чтобы пользователь мог им всегда воспользоватся. 22 | * При нажатии на каждый элемент меню страница плавно прокручивается до соответствующего блока на странице. 23 | 24 | ![](./task/images/001.jpg) 25 | 26 | * Создайте три слайда с произвольным изображением и текстом. 27 | * Смена слайдов должна присходить с интервалом в 3с. 28 | * По нажатию стелок навигации, автоматическая смена слайдов должна приостанавливатся, 29 | пока пользователь листает слайды вручную. Если в течении 5с пользователь не нажимал на элементы навигации, 30 | должна возобновиться автоматическая смена слайдов. 31 | 32 | * При нажатии на кнопку Explore Now страница плавно прокручивается до блока портфолио. 33 | * При нажатии на кнопку Purchase Now страница плавно прокручивается до блока контактов. 34 | 35 | * Для реализации плавной прокрутки страницы разрешается использовать сторонние ресурсы(например, https://github.com/fisshy/react-scroll). 36 | 37 | ### Блок Our Services 38 | ![](./task/images/002.jpg) 39 | 40 | * При клике по каждой из иконок сервисов открывается вкладка с изображением(используйте произвольные изображения) и текстом описания сервиса. 41 | * Используйте маршрутизацию для реализации переключения вкладок. 42 | 43 | ### Блок About Our Company 44 | ![](./task/images/003.jpg) 45 | 46 | * Блок с описанием компании. 47 | * По умолчанию открыта вкладка Our Skills. 48 | 49 | * Когда блок только появился в области видимости страницы, в течении 3 секунд ширина блоков диаграммы изменяется от 0 до значений, указанных в макете. 50 | * Для создания анимации используйте аддон ReactCSSTransitionGroup. Установка аддона: 51 | 52 | ``` 53 | npm install react-addons-css-transition-group 54 | ``` 55 | * При переключении вкладок отображается соответствующая информация(см. макет). 56 | 57 | ### Блок портфолио 58 | ![](./task/images/004.jpg) 59 | 60 | * Добавьте произвольные изображения в портфолио. 61 | * Реализуйте фильтрацию изображений по категориям. 62 | * При наведении курсора мыши на изображение над ним появляется полупрозрачный слой с информацией о том к какой категории относится данное изображение. 63 | 64 | ### Блок Our Team 65 | ![](./task/images/005.jpg) 66 | 67 | * Добавьте произвольное фото для членов команды. 68 | * При наведении мыши на иконки ссылок социальных сетей они меняют цвет. 69 | 70 | ### Блок со статистикой достижений 71 | ![](./task/images/006.jpg) 72 | 73 | * Когда блок только появился в видимой области страницы, течении 3 секунд происходит отсчет от 0 до значений, указанных в макете. 74 | 75 | ### Блок News 76 | ![](./task/images/007.jpg) 77 | 78 | * Добавьте произвольные изображения в превью новостей. 79 | * Загрузите описание новостей из JSON-файла(файл data.json в папке project). 80 | * Изначально после загрузки страницы отображается 8 новостей. 81 | 82 | * При нажатии на изображение выполняется переход по пути '/id', где id - id новости. На открывшейся странице отображается дата и текст новости. 83 | * Маршрутизацию нужно реализовать без перезагрузки страницы. 84 | 85 | * При нажатии на кнопку load more на странице должны отображаются следующие 8 новостей из файла data.json. 86 | 87 | ### Блок Feedback 88 | ![](./task/images/008.jpg) 89 | 90 | * Форма с полями Title и Message. Поля обязательны для заполнения. 91 | * При нажатии на кнопку Add Comment в окно сообщений добавляется панель сообщения, содержащая заголовок и текст сообщения(данные из формы). 92 | * Данные сообщений сохраняются в массив messages (каждый элемент массива - объект со свойствами id, title, text). 93 | * При нажатии на икноку удаления в верхнем правом углу панели сообщения, оно удаляется (не только со страницы, но также из массива messages). 94 | 95 | * Сохраните данные массива messages в cookies и используйте их для отображения прошлых сообщений при перезагрузке страницы. 96 | 97 | * Для решения задачи используйте Webpack и синтаксис ES6. 98 | 99 | ### Блок контактов 100 | ![](./task/images/009.jpg) 101 | 102 | * Добавьте в блок карту с координатами компании(используйте сервис Google maps). 103 | 104 | * Форма с полями Name, Email, Message. Валидация формы происходит при нажатии на клавиши. При вводе пользователем некорректных данных в поле ввода под этим полем сразу отображается сообщение об ошибке. Сообщение об ошибке сразу же скрывается, если пользователь ввел корректные данные. 105 | * В поле Name допускаются только буквы английского алфавита. 106 | * В поле Email допускаются толко буквы английского алфавита, цифры, знак подчеркивание и симвом @. 107 | * В поле Message допускаются любые символы. Минимальная длина сообщения - 20 символов. 108 | 109 | ### Footer 110 | ![](./task/images/010.jpg) 111 | 112 | * Копирайт и кнопка вверх. 113 | * При нажатии на кнопку страница плавно прокручивается в начало. 114 | 115 | -------------------------------------------------------------------------------- /css/grid12.css: -------------------------------------------------------------------------------- 1 | @-ms-viewport { 2 | width: device-width; 3 | } 4 | .visible-xs, 5 | .visible-sm, 6 | .visible-md, 7 | .visible-lg { 8 | display: none !important; 9 | } 10 | .visible-xs-block, 11 | .visible-xs-inline, 12 | .visible-xs-inline-block, 13 | .visible-sm-block, 14 | .visible-sm-inline, 15 | .visible-sm-inline-block, 16 | .visible-md-block, 17 | .visible-md-inline, 18 | .visible-md-inline-block, 19 | .visible-lg-block, 20 | .visible-lg-inline, 21 | .visible-lg-inline-block { 22 | display: none !important; 23 | } 24 | @media (max-width: 767px) { 25 | .visible-xs { 26 | display: block !important; 27 | } 28 | table.visible-xs { 29 | display: table; 30 | } 31 | tr.visible-xs { 32 | display: table-row !important; 33 | } 34 | th.visible-xs, 35 | td.visible-xs { 36 | display: table-cell !important; 37 | } 38 | } 39 | @media (max-width: 767px) { 40 | .visible-xs-block { 41 | display: block !important; 42 | } 43 | } 44 | @media (max-width: 767px) { 45 | .visible-xs-inline { 46 | display: inline !important; 47 | } 48 | } 49 | @media (max-width: 767px) { 50 | .visible-xs-inline-block { 51 | display: inline-block !important; 52 | } 53 | } 54 | @media (min-width: 768px) and (max-width: 991px) { 55 | .visible-sm { 56 | display: block !important; 57 | } 58 | table.visible-sm { 59 | display: table; 60 | } 61 | tr.visible-sm { 62 | display: table-row !important; 63 | } 64 | th.visible-sm, 65 | td.visible-sm { 66 | display: table-cell !important; 67 | } 68 | } 69 | @media (min-width: 768px) and (max-width: 991px) { 70 | .visible-sm-block { 71 | display: block !important; 72 | } 73 | } 74 | @media (min-width: 768px) and (max-width: 991px) { 75 | .visible-sm-inline { 76 | display: inline !important; 77 | } 78 | } 79 | @media (min-width: 768px) and (max-width: 991px) { 80 | .visible-sm-inline-block { 81 | display: inline-block !important; 82 | } 83 | } 84 | @media (min-width: 992px) and (max-width: 1199px) { 85 | .visible-md { 86 | display: block !important; 87 | } 88 | table.visible-md { 89 | display: table; 90 | } 91 | tr.visible-md { 92 | display: table-row !important; 93 | } 94 | th.visible-md, 95 | td.visible-md { 96 | display: table-cell !important; 97 | } 98 | } 99 | @media (min-width: 992px) and (max-width: 1199px) { 100 | .visible-md-block { 101 | display: block !important; 102 | } 103 | } 104 | @media (min-width: 992px) and (max-width: 1199px) { 105 | .visible-md-inline { 106 | display: inline !important; 107 | } 108 | } 109 | @media (min-width: 992px) and (max-width: 1199px) { 110 | .visible-md-inline-block { 111 | display: inline-block !important; 112 | } 113 | } 114 | @media (min-width: 1200px) { 115 | .visible-lg { 116 | display: block !important; 117 | } 118 | table.visible-lg { 119 | display: table; 120 | } 121 | tr.visible-lg { 122 | display: table-row !important; 123 | } 124 | th.visible-lg, 125 | td.visible-lg { 126 | display: table-cell !important; 127 | } 128 | } 129 | @media (min-width: 1200px) { 130 | .visible-lg-block { 131 | display: block !important; 132 | } 133 | } 134 | @media (min-width: 1200px) { 135 | .visible-lg-inline { 136 | display: inline !important; 137 | } 138 | } 139 | @media (min-width: 1200px) { 140 | .visible-lg-inline-block { 141 | display: inline-block !important; 142 | } 143 | } 144 | @media (max-width: 767px) { 145 | .hidden-xs { 146 | display: none !important; 147 | } 148 | } 149 | @media (min-width: 768px) and (max-width: 991px) { 150 | .hidden-sm { 151 | display: none !important; 152 | } 153 | } 154 | @media (min-width: 992px) and (max-width: 1199px) { 155 | .hidden-md { 156 | display: none !important; 157 | } 158 | } 159 | @media (min-width: 1200px) { 160 | .hidden-lg { 161 | display: none !important; 162 | } 163 | } 164 | .visible-print { 165 | display: none !important; 166 | } 167 | @media print { 168 | .visible-print { 169 | display: block !important; 170 | } 171 | table.visible-print { 172 | display: table; 173 | } 174 | tr.visible-print { 175 | display: table-row !important; 176 | } 177 | th.visible-print, 178 | td.visible-print { 179 | display: table-cell !important; 180 | } 181 | } 182 | .visible-print-block { 183 | display: none !important; 184 | } 185 | @media print { 186 | .visible-print-block { 187 | display: block !important; 188 | } 189 | } 190 | .visible-print-inline { 191 | display: none !important; 192 | } 193 | @media print { 194 | .visible-print-inline { 195 | display: inline !important; 196 | } 197 | } 198 | .visible-print-inline-block { 199 | display: none !important; 200 | } 201 | @media print { 202 | .visible-print-inline-block { 203 | display: inline-block !important; 204 | } 205 | } 206 | @media print { 207 | .hidden-print { 208 | display: none !important; 209 | } 210 | } 211 | .container { 212 | margin-right: auto; 213 | margin-left: auto; 214 | padding-left: 15px; 215 | padding-right: 15px; 216 | } 217 | @media (min-width: 768px) { 218 | .container { 219 | width: 750px; 220 | } 221 | } 222 | @media (min-width: 992px) { 223 | .container { 224 | width: 970px; 225 | } 226 | } 227 | @media (min-width: 1200px) { 228 | .container { 229 | width: 1170px; 230 | } 231 | } 232 | .container-fluid { 233 | margin-right: auto; 234 | margin-left: auto; 235 | padding-left: 15px; 236 | padding-right: 15px; 237 | } 238 | .row { 239 | margin-left: -15px; 240 | margin-right: -15px; 241 | } 242 | .col, .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { 243 | position: relative; 244 | min-height: 1px; 245 | padding-left: 15px; 246 | padding-right: 15px; 247 | } 248 | .col, .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { 249 | float: left; 250 | } 251 | .col-xs-12 { 252 | width: 100%; 253 | } 254 | .col-xs-11 { 255 | width: 91.66666667%; 256 | } 257 | .col-xs-10 { 258 | width: 83.33333333%; 259 | } 260 | .col-xs-9 { 261 | width: 75%; 262 | } 263 | .col-xs-8 { 264 | width: 66.66666667%; 265 | } 266 | .col-xs-7 { 267 | width: 58.33333333%; 268 | } 269 | .col-xs-6 { 270 | width: 50%; 271 | } 272 | .col-xs-5 { 273 | width: 41.66666667%; 274 | } 275 | .col-xs-4 { 276 | width: 33.33333333%; 277 | } 278 | .col-xs-3 { 279 | width: 25%; 280 | } 281 | .col-xs-2 { 282 | width: 16.66666667%; 283 | } 284 | .col-xs-1 { 285 | width: 8.33333333%; 286 | } 287 | .col-xs-pull-12 { 288 | right: 100%; 289 | } 290 | .col-xs-pull-11 { 291 | right: 91.66666667%; 292 | } 293 | .col-xs-pull-10 { 294 | right: 83.33333333%; 295 | } 296 | .col-xs-pull-9 { 297 | right: 75%; 298 | } 299 | .col-xs-pull-8 { 300 | right: 66.66666667%; 301 | } 302 | .col-xs-pull-7 { 303 | right: 58.33333333%; 304 | } 305 | .col-xs-pull-6 { 306 | right: 50%; 307 | } 308 | .col-xs-pull-5 { 309 | right: 41.66666667%; 310 | } 311 | .col-xs-pull-4 { 312 | right: 33.33333333%; 313 | } 314 | .col-xs-pull-3 { 315 | right: 25%; 316 | } 317 | .col-xs-pull-2 { 318 | right: 16.66666667%; 319 | } 320 | .col-xs-pull-1 { 321 | right: 8.33333333%; 322 | } 323 | .col-xs-pull-0 { 324 | right: auto; 325 | } 326 | .col-xs-push-12 { 327 | left: 100%; 328 | } 329 | .col-xs-push-11 { 330 | left: 91.66666667%; 331 | } 332 | .col-xs-push-10 { 333 | left: 83.33333333%; 334 | } 335 | .col-xs-push-9 { 336 | left: 75%; 337 | } 338 | .col-xs-push-8 { 339 | left: 66.66666667%; 340 | } 341 | .col-xs-push-7 { 342 | left: 58.33333333%; 343 | } 344 | .col-xs-push-6 { 345 | left: 50%; 346 | } 347 | .col-xs-push-5 { 348 | left: 41.66666667%; 349 | } 350 | .col-xs-push-4 { 351 | left: 33.33333333%; 352 | } 353 | .col-xs-push-3 { 354 | left: 25%; 355 | } 356 | .col-xs-push-2 { 357 | left: 16.66666667%; 358 | } 359 | .col-xs-push-1 { 360 | left: 8.33333333%; 361 | } 362 | .col-xs-push-0 { 363 | left: auto; 364 | } 365 | .col-xs-offset-12 { 366 | margin-left: 100%; 367 | } 368 | .col-xs-offset-11 { 369 | margin-left: 91.66666667%; 370 | } 371 | .col-xs-offset-10 { 372 | margin-left: 83.33333333%; 373 | } 374 | .col-xs-offset-9 { 375 | margin-left: 75%; 376 | } 377 | .col-xs-offset-8 { 378 | margin-left: 66.66666667%; 379 | } 380 | .col-xs-offset-7 { 381 | margin-left: 58.33333333%; 382 | } 383 | .col-xs-offset-6 { 384 | margin-left: 50%; 385 | } 386 | .col-xs-offset-5 { 387 | margin-left: 41.66666667%; 388 | } 389 | .col-xs-offset-4 { 390 | margin-left: 33.33333333%; 391 | } 392 | .col-xs-offset-3 { 393 | margin-left: 25%; 394 | } 395 | .col-xs-offset-2 { 396 | margin-left: 16.66666667%; 397 | } 398 | .col-xs-offset-1 { 399 | margin-left: 8.33333333%; 400 | } 401 | .col-xs-offset-0 { 402 | margin-left: 0%; 403 | } 404 | @media (min-width: 768px) { 405 | .col, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { 406 | float: left; 407 | } 408 | .col-sm-12 { 409 | width: 100%; 410 | } 411 | .col-sm-11 { 412 | width: 91.66666667%; 413 | } 414 | .col-sm-10 { 415 | width: 83.33333333%; 416 | } 417 | .col-sm-9 { 418 | width: 75%; 419 | } 420 | .col-sm-8 { 421 | width: 66.66666667%; 422 | } 423 | .col-sm-7 { 424 | width: 58.33333333%; 425 | } 426 | .col-sm-6 { 427 | width: 50%; 428 | } 429 | .col-sm-5 { 430 | width: 41.66666667%; 431 | } 432 | .col-sm-4 { 433 | width: 33.33333333%; 434 | } 435 | .col-sm-3 { 436 | width: 25%; 437 | } 438 | .col-sm-2 { 439 | width: 16.66666667%; 440 | } 441 | .col-sm-1 { 442 | width: 8.33333333%; 443 | } 444 | .col-sm-pull-12 { 445 | right: 100%; 446 | } 447 | .col-sm-pull-11 { 448 | right: 91.66666667%; 449 | } 450 | .col-sm-pull-10 { 451 | right: 83.33333333%; 452 | } 453 | .col-sm-pull-9 { 454 | right: 75%; 455 | } 456 | .col-sm-pull-8 { 457 | right: 66.66666667%; 458 | } 459 | .col-sm-pull-7 { 460 | right: 58.33333333%; 461 | } 462 | .col-sm-pull-6 { 463 | right: 50%; 464 | } 465 | .col-sm-pull-5 { 466 | right: 41.66666667%; 467 | } 468 | .col-sm-pull-4 { 469 | right: 33.33333333%; 470 | } 471 | .col-sm-pull-3 { 472 | right: 25%; 473 | } 474 | .col-sm-pull-2 { 475 | right: 16.66666667%; 476 | } 477 | .col-sm-pull-1 { 478 | right: 8.33333333%; 479 | } 480 | .col-sm-pull-0 { 481 | right: auto; 482 | } 483 | .col-sm-push-12 { 484 | left: 100%; 485 | } 486 | .col-sm-push-11 { 487 | left: 91.66666667%; 488 | } 489 | .col-sm-push-10 { 490 | left: 83.33333333%; 491 | } 492 | .col-sm-push-9 { 493 | left: 75%; 494 | } 495 | .col-sm-push-8 { 496 | left: 66.66666667%; 497 | } 498 | .col-sm-push-7 { 499 | left: 58.33333333%; 500 | } 501 | .col-sm-push-6 { 502 | left: 50%; 503 | } 504 | .col-sm-push-5 { 505 | left: 41.66666667%; 506 | } 507 | .col-sm-push-4 { 508 | left: 33.33333333%; 509 | } 510 | .col-sm-push-3 { 511 | left: 25%; 512 | } 513 | .col-sm-push-2 { 514 | left: 16.66666667%; 515 | } 516 | .col-sm-push-1 { 517 | left: 8.33333333%; 518 | } 519 | .col-sm-push-0 { 520 | left: auto; 521 | } 522 | .col-sm-offset-12 { 523 | margin-left: 100%; 524 | } 525 | .col-sm-offset-11 { 526 | margin-left: 91.66666667%; 527 | } 528 | .col-sm-offset-10 { 529 | margin-left: 83.33333333%; 530 | } 531 | .col-sm-offset-9 { 532 | margin-left: 75%; 533 | } 534 | .col-sm-offset-8 { 535 | margin-left: 66.66666667%; 536 | } 537 | .col-sm-offset-7 { 538 | margin-left: 58.33333333%; 539 | } 540 | .col-sm-offset-6 { 541 | margin-left: 50%; 542 | } 543 | .col-sm-offset-5 { 544 | margin-left: 41.66666667%; 545 | } 546 | .col-sm-offset-4 { 547 | margin-left: 33.33333333%; 548 | } 549 | .col-sm-offset-3 { 550 | margin-left: 25%; 551 | } 552 | .col-sm-offset-2 { 553 | margin-left: 16.66666667%; 554 | } 555 | .col-sm-offset-1 { 556 | margin-left: 8.33333333%; 557 | } 558 | .col-sm-offset-0 { 559 | margin-left: 0%; 560 | } 561 | } 562 | @media (min-width: 992px) { 563 | .col, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { 564 | float: left; 565 | } 566 | .col-md-12 { 567 | width: 100%; 568 | } 569 | .col-md-11 { 570 | width: 91.66666667%; 571 | } 572 | .col-md-10 { 573 | width: 83.33333333%; 574 | } 575 | .col-md-9 { 576 | width: 75%; 577 | } 578 | .col-md-8 { 579 | width: 66.66666667%; 580 | } 581 | .col-md-7 { 582 | width: 58.33333333%; 583 | } 584 | .col-md-6 { 585 | width: 50%; 586 | } 587 | .col-md-5 { 588 | width: 41.66666667%; 589 | } 590 | .col-md-4 { 591 | width: 33.33333333%; 592 | } 593 | .col-md-3 { 594 | width: 25%; 595 | } 596 | .col-md-2 { 597 | width: 16.66666667%; 598 | } 599 | .col-md-1 { 600 | width: 8.33333333%; 601 | } 602 | .col-md-pull-12 { 603 | right: 100%; 604 | } 605 | .col-md-pull-11 { 606 | right: 91.66666667%; 607 | } 608 | .col-md-pull-10 { 609 | right: 83.33333333%; 610 | } 611 | .col-md-pull-9 { 612 | right: 75%; 613 | } 614 | .col-md-pull-8 { 615 | right: 66.66666667%; 616 | } 617 | .col-md-pull-7 { 618 | right: 58.33333333%; 619 | } 620 | .col-md-pull-6 { 621 | right: 50%; 622 | } 623 | .col-md-pull-5 { 624 | right: 41.66666667%; 625 | } 626 | .col-md-pull-4 { 627 | right: 33.33333333%; 628 | } 629 | .col-md-pull-3 { 630 | right: 25%; 631 | } 632 | .col-md-pull-2 { 633 | right: 16.66666667%; 634 | } 635 | .col-md-pull-1 { 636 | right: 8.33333333%; 637 | } 638 | .col-md-pull-0 { 639 | right: auto; 640 | } 641 | .col-md-push-12 { 642 | left: 100%; 643 | } 644 | .col-md-push-11 { 645 | left: 91.66666667%; 646 | } 647 | .col-md-push-10 { 648 | left: 83.33333333%; 649 | } 650 | .col-md-push-9 { 651 | left: 75%; 652 | } 653 | .col-md-push-8 { 654 | left: 66.66666667%; 655 | } 656 | .col-md-push-7 { 657 | left: 58.33333333%; 658 | } 659 | .col-md-push-6 { 660 | left: 50%; 661 | } 662 | .col-md-push-5 { 663 | left: 41.66666667%; 664 | } 665 | .col-md-push-4 { 666 | left: 33.33333333%; 667 | } 668 | .col-md-push-3 { 669 | left: 25%; 670 | } 671 | .col-md-push-2 { 672 | left: 16.66666667%; 673 | } 674 | .col-md-push-1 { 675 | left: 8.33333333%; 676 | } 677 | .col-md-push-0 { 678 | left: auto; 679 | } 680 | .col-md-offset-12 { 681 | margin-left: 100%; 682 | } 683 | .col-md-offset-11 { 684 | margin-left: 91.66666667%; 685 | } 686 | .col-md-offset-10 { 687 | margin-left: 83.33333333%; 688 | } 689 | .col-md-offset-9 { 690 | margin-left: 75%; 691 | } 692 | .col-md-offset-8 { 693 | margin-left: 66.66666667%; 694 | } 695 | .col-md-offset-7 { 696 | margin-left: 58.33333333%; 697 | } 698 | .col-md-offset-6 { 699 | margin-left: 50%; 700 | } 701 | .col-md-offset-5 { 702 | margin-left: 41.66666667%; 703 | } 704 | .col-md-offset-4 { 705 | margin-left: 33.33333333%; 706 | } 707 | .col-md-offset-3 { 708 | margin-left: 25%; 709 | } 710 | .col-md-offset-2 { 711 | margin-left: 16.66666667%; 712 | } 713 | .col-md-offset-1 { 714 | margin-left: 8.33333333%; 715 | } 716 | .col-md-offset-0 { 717 | margin-left: 0%; 718 | } 719 | } 720 | @media (min-width: 1200px) { 721 | .col, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { 722 | float: left; 723 | } 724 | .col-lg-12 { 725 | width: 100%; 726 | } 727 | .col-lg-11 { 728 | width: 91.66666667%; 729 | } 730 | .col-lg-10 { 731 | width: 83.33333333%; 732 | } 733 | .col-lg-9 { 734 | width: 75%; 735 | } 736 | .col-lg-8 { 737 | width: 66.66666667%; 738 | } 739 | .col-lg-7 { 740 | width: 58.33333333%; 741 | } 742 | .col-lg-6 { 743 | width: 50%; 744 | } 745 | .col-lg-5 { 746 | width: 41.66666667%; 747 | } 748 | .col-lg-4 { 749 | width: 33.33333333%; 750 | } 751 | .col-lg-3 { 752 | width: 25%; 753 | } 754 | .col-lg-2 { 755 | width: 16.66666667%; 756 | } 757 | .col-lg-1 { 758 | width: 8.33333333%; 759 | } 760 | .col-lg-pull-12 { 761 | right: 100%; 762 | } 763 | .col-lg-pull-11 { 764 | right: 91.66666667%; 765 | } 766 | .col-lg-pull-10 { 767 | right: 83.33333333%; 768 | } 769 | .col-lg-pull-9 { 770 | right: 75%; 771 | } 772 | .col-lg-pull-8 { 773 | right: 66.66666667%; 774 | } 775 | .col-lg-pull-7 { 776 | right: 58.33333333%; 777 | } 778 | .col-lg-pull-6 { 779 | right: 50%; 780 | } 781 | .col-lg-pull-5 { 782 | right: 41.66666667%; 783 | } 784 | .col-lg-pull-4 { 785 | right: 33.33333333%; 786 | } 787 | .col-lg-pull-3 { 788 | right: 25%; 789 | } 790 | .col-lg-pull-2 { 791 | right: 16.66666667%; 792 | } 793 | .col-lg-pull-1 { 794 | right: 8.33333333%; 795 | } 796 | .col-lg-pull-0 { 797 | right: auto; 798 | } 799 | .col-lg-push-12 { 800 | left: 100%; 801 | } 802 | .col-lg-push-11 { 803 | left: 91.66666667%; 804 | } 805 | .col-lg-push-10 { 806 | left: 83.33333333%; 807 | } 808 | .col-lg-push-9 { 809 | left: 75%; 810 | } 811 | .col-lg-push-8 { 812 | left: 66.66666667%; 813 | } 814 | .col-lg-push-7 { 815 | left: 58.33333333%; 816 | } 817 | .col-lg-push-6 { 818 | left: 50%; 819 | } 820 | .col-lg-push-5 { 821 | left: 41.66666667%; 822 | } 823 | .col-lg-push-4 { 824 | left: 33.33333333%; 825 | } 826 | .col-lg-push-3 { 827 | left: 25%; 828 | } 829 | .col-lg-push-2 { 830 | left: 16.66666667%; 831 | } 832 | .col-lg-push-1 { 833 | left: 8.33333333%; 834 | } 835 | .col-lg-push-0 { 836 | left: auto; 837 | } 838 | .col-lg-offset-12 { 839 | margin-left: 100%; 840 | } 841 | .col-lg-offset-11 { 842 | margin-left: 91.66666667%; 843 | } 844 | .col-lg-offset-10 { 845 | margin-left: 83.33333333%; 846 | } 847 | .col-lg-offset-9 { 848 | margin-left: 75%; 849 | } 850 | .col-lg-offset-8 { 851 | margin-left: 66.66666667%; 852 | } 853 | .col-lg-offset-7 { 854 | margin-left: 58.33333333%; 855 | } 856 | .col-lg-offset-6 { 857 | margin-left: 50%; 858 | } 859 | .col-lg-offset-5 { 860 | margin-left: 41.66666667%; 861 | } 862 | .col-lg-offset-4 { 863 | margin-left: 33.33333333%; 864 | } 865 | .col-lg-offset-3 { 866 | margin-left: 25%; 867 | } 868 | .col-lg-offset-2 { 869 | margin-left: 16.66666667%; 870 | } 871 | .col-lg-offset-1 { 872 | margin-left: 8.33333333%; 873 | } 874 | .col-lg-offset-0 { 875 | margin-left: 0%; 876 | } 877 | } 878 | .clearfix, 879 | .clearfix:before, 880 | .clearfix:after, 881 | .container:before, 882 | .container:after, 883 | .container-fluid:before, 884 | .container-fluid:after, 885 | .row:before, 886 | .row:after { 887 | content: " "; 888 | display: table; 889 | } 890 | .clearfix:after, 891 | .container:after, 892 | .container-fluid:after, 893 | .row:after { 894 | clear: both; 895 | } 896 | .center-block { 897 | display: block; 898 | margin-left: auto; 899 | margin-right: auto; 900 | } 901 | .pull-right { 902 | float: right !important; 903 | } 904 | .pull-left { 905 | float: left !important; 906 | } 907 | *, 908 | *:before, 909 | *:after { 910 | -webkit-box-sizing: border-box; 911 | -moz-box-sizing: border-box; 912 | box-sizing: border-box; 913 | } -------------------------------------------------------------------------------- /css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /** 4 | * 1. Change the default font family in all browsers (opinionated). 5 | * 2. Prevent adjustments of font size after orientation changes in IE and iOS. 6 | */ 7 | 8 | html { 9 | font-family: sans-serif; /* 1 */ 10 | -ms-text-size-adjust: 100%; /* 2 */ 11 | -webkit-text-size-adjust: 100%; /* 2 */ 12 | } 13 | 14 | /** 15 | * Remove the margin in all browsers (opinionated). 16 | */ 17 | 18 | body { 19 | margin: 0; 20 | } 21 | 22 | /* HTML5 display definitions 23 | ========================================================================== */ 24 | 25 | /** 26 | * Add the correct display in IE 9-. 27 | * 1. Add the correct display in Edge, IE, and Firefox. 28 | * 2. Add the correct display in IE. 29 | */ 30 | 31 | article, 32 | aside, 33 | details, /* 1 */ 34 | figcaption, 35 | figure, 36 | footer, 37 | header, 38 | main, /* 2 */ 39 | menu, 40 | nav, 41 | section, 42 | summary { /* 1 */ 43 | display: block; 44 | } 45 | 46 | /** 47 | * Add the correct display in IE 9-. 48 | */ 49 | 50 | audio, 51 | canvas, 52 | progress, 53 | video { 54 | display: inline-block; 55 | } 56 | 57 | /** 58 | * Add the correct display in iOS 4-7. 59 | */ 60 | 61 | audio:not([controls]) { 62 | display: none; 63 | height: 0; 64 | } 65 | 66 | /** 67 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 68 | */ 69 | 70 | progress { 71 | vertical-align: baseline; 72 | } 73 | 74 | /** 75 | * Add the correct display in IE 10-. 76 | * 1. Add the correct display in IE. 77 | */ 78 | 79 | template, /* 1 */ 80 | [hidden] { 81 | display: none; 82 | } 83 | 84 | /* Links 85 | ========================================================================== */ 86 | 87 | /** 88 | * 1. Remove the gray background on active links in IE 10. 89 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. 90 | */ 91 | 92 | a { 93 | background-color: transparent; /* 1 */ 94 | -webkit-text-decoration-skip: objects; /* 2 */ 95 | } 96 | 97 | /** 98 | * Remove the outline on focused links when they are also active or hovered 99 | * in all browsers (opinionated). 100 | */ 101 | 102 | a:active, 103 | a:hover { 104 | outline-width: 0; 105 | } 106 | 107 | /* Text-level semantics 108 | ========================================================================== */ 109 | 110 | /** 111 | * 1. Remove the bottom border in Firefox 39-. 112 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 113 | */ 114 | 115 | abbr[title] { 116 | border-bottom: none; /* 1 */ 117 | text-decoration: underline; /* 2 */ 118 | text-decoration: underline dotted; /* 2 */ 119 | } 120 | 121 | /** 122 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6. 123 | */ 124 | 125 | b, 126 | strong { 127 | font-weight: inherit; 128 | } 129 | 130 | /** 131 | * Add the correct font weight in Chrome, Edge, and Safari. 132 | */ 133 | 134 | b, 135 | strong { 136 | font-weight: bolder; 137 | } 138 | 139 | /** 140 | * Add the correct font style in Android 4.3-. 141 | */ 142 | 143 | dfn { 144 | font-style: italic; 145 | } 146 | 147 | /** 148 | * Correct the font size and margin on `h1` elements within `section` and 149 | * `article` contexts in Chrome, Firefox, and Safari. 150 | */ 151 | 152 | h1 { 153 | font-size: 2em; 154 | margin: 0.67em 0; 155 | } 156 | 157 | /** 158 | * Add the correct background and color in IE 9-. 159 | */ 160 | 161 | mark { 162 | background-color: #ff0; 163 | color: #000; 164 | } 165 | 166 | /** 167 | * Add the correct font size in all browsers. 168 | */ 169 | 170 | small { 171 | font-size: 80%; 172 | } 173 | 174 | /** 175 | * Prevent `sub` and `sup` elements from affecting the line height in 176 | * all browsers. 177 | */ 178 | 179 | sub, 180 | sup { 181 | font-size: 75%; 182 | line-height: 0; 183 | position: relative; 184 | vertical-align: baseline; 185 | } 186 | 187 | sub { 188 | bottom: -0.25em; 189 | } 190 | 191 | sup { 192 | top: -0.5em; 193 | } 194 | 195 | /* Embedded content 196 | ========================================================================== */ 197 | 198 | /** 199 | * Remove the border on images inside links in IE 10-. 200 | */ 201 | 202 | img { 203 | border-style: none; 204 | } 205 | 206 | /** 207 | * Hide the overflow in IE. 208 | */ 209 | 210 | svg:not(:root) { 211 | overflow: hidden; 212 | } 213 | 214 | /* Grouping content 215 | ========================================================================== */ 216 | 217 | /** 218 | * 1. Correct the inheritance and scaling of font size in all browsers. 219 | * 2. Correct the odd `em` font sizing in all browsers. 220 | */ 221 | 222 | code, 223 | kbd, 224 | pre, 225 | samp { 226 | font-family: monospace, monospace; /* 1 */ 227 | font-size: 1em; /* 2 */ 228 | } 229 | 230 | /** 231 | * Add the correct margin in IE 8. 232 | */ 233 | 234 | figure { 235 | margin: 1em 40px; 236 | } 237 | 238 | /** 239 | * 1. Add the correct box sizing in Firefox. 240 | * 2. Show the overflow in Edge and IE. 241 | */ 242 | 243 | hr { 244 | box-sizing: content-box; /* 1 */ 245 | height: 0; /* 1 */ 246 | overflow: visible; /* 2 */ 247 | } 248 | 249 | /* Forms 250 | ========================================================================== */ 251 | 252 | /** 253 | * 1. Change font properties to `inherit` in all browsers (opinionated). 254 | * 2. Remove the margin in Firefox and Safari. 255 | */ 256 | 257 | button, 258 | input, 259 | select, 260 | textarea { 261 | font: inherit; /* 1 */ 262 | margin: 0; /* 2 */ 263 | } 264 | 265 | /** 266 | * Restore the font weight unset by the previous rule. 267 | */ 268 | 269 | optgroup { 270 | font-weight: bold; 271 | } 272 | 273 | /** 274 | * Show the overflow in IE. 275 | * 1. Show the overflow in Edge. 276 | */ 277 | 278 | button, 279 | input { /* 1 */ 280 | overflow: visible; 281 | } 282 | 283 | /** 284 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 285 | * 1. Remove the inheritance of text transform in Firefox. 286 | */ 287 | 288 | button, 289 | select { /* 1 */ 290 | text-transform: none; 291 | } 292 | 293 | /** 294 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 295 | * controls in Android 4. 296 | * 2. Correct the inability to style clickable types in iOS and Safari. 297 | */ 298 | 299 | button, 300 | html [type="button"], /* 1 */ 301 | [type="reset"], 302 | [type="submit"] { 303 | -webkit-appearance: button; /* 2 */ 304 | } 305 | 306 | /** 307 | * Remove the inner border and padding in Firefox. 308 | */ 309 | 310 | button::-moz-focus-inner, 311 | [type="button"]::-moz-focus-inner, 312 | [type="reset"]::-moz-focus-inner, 313 | [type="submit"]::-moz-focus-inner { 314 | border-style: none; 315 | padding: 0; 316 | } 317 | 318 | /** 319 | * Restore the focus styles unset by the previous rule. 320 | */ 321 | 322 | button:-moz-focusring, 323 | [type="button"]:-moz-focusring, 324 | [type="reset"]:-moz-focusring, 325 | [type="submit"]:-moz-focusring { 326 | outline: 1px dotted ButtonText; 327 | } 328 | 329 | /** 330 | * Change the border, margin, and padding in all browsers (opinionated). 331 | */ 332 | 333 | fieldset { 334 | border: 1px solid #c0c0c0; 335 | margin: 0 2px; 336 | padding: 0.35em 0.625em 0.75em; 337 | } 338 | 339 | /** 340 | * 1. Correct the text wrapping in Edge and IE. 341 | * 2. Correct the color inheritance from `fieldset` elements in IE. 342 | * 3. Remove the padding so developers are not caught out when they zero out 343 | * `fieldset` elements in all browsers. 344 | */ 345 | 346 | legend { 347 | box-sizing: border-box; /* 1 */ 348 | color: inherit; /* 2 */ 349 | display: table; /* 1 */ 350 | max-width: 100%; /* 1 */ 351 | padding: 0; /* 3 */ 352 | white-space: normal; /* 1 */ 353 | } 354 | 355 | /** 356 | * Remove the default vertical scrollbar in IE. 357 | */ 358 | 359 | textarea { 360 | overflow: auto; 361 | } 362 | 363 | /** 364 | * 1. Add the correct box sizing in IE 10-. 365 | * 2. Remove the padding in IE 10-. 366 | */ 367 | 368 | [type="checkbox"], 369 | [type="radio"] { 370 | box-sizing: border-box; /* 1 */ 371 | padding: 0; /* 2 */ 372 | } 373 | 374 | /** 375 | * Correct the cursor style of increment and decrement buttons in Chrome. 376 | */ 377 | 378 | [type="number"]::-webkit-inner-spin-button, 379 | [type="number"]::-webkit-outer-spin-button { 380 | height: auto; 381 | } 382 | 383 | /** 384 | * 1. Correct the odd appearance in Chrome and Safari. 385 | * 2. Correct the outline style in Safari. 386 | */ 387 | 388 | [type="search"] { 389 | -webkit-appearance: textfield; /* 1 */ 390 | outline-offset: -2px; /* 2 */ 391 | } 392 | 393 | /** 394 | * Remove the inner padding and cancel buttons in Chrome and Safari on OS X. 395 | */ 396 | 397 | [type="search"]::-webkit-search-cancel-button, 398 | [type="search"]::-webkit-search-decoration { 399 | -webkit-appearance: none; 400 | } 401 | 402 | /** 403 | * Correct the text style of placeholders in Chrome, Edge, and Safari. 404 | */ 405 | 406 | ::-webkit-input-placeholder { 407 | color: inherit; 408 | opacity: 0.54; 409 | } 410 | 411 | /** 412 | * 1. Correct the inability to style clickable types in iOS and Safari. 413 | * 2. Change font properties to `inherit` in Safari. 414 | */ 415 | 416 | ::-webkit-file-upload-button { 417 | -webkit-appearance: button; /* 1 */ 418 | font: inherit; /* 2 */ 419 | } 420 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | @import "normalize.css"; 2 | 3 | @font-face { 4 | font-family: Montserrat; 5 | font-weight: 700; 6 | src: url("../fonts/Montserrat-Bold.otf") 7 | } 8 | 9 | @font-face { 10 | font-family: Montserrat; 11 | font-weight: 600; 12 | src: url("../fonts/Montserrat-SemiBold.otf") 13 | } 14 | 15 | @font-face { 16 | font-family: Montserrat; 17 | font-weight: 300; 18 | src: url("../fonts/Montserrat-Light.otf") 19 | } 20 | 21 | @font-face { 22 | font-family: Montserrat; 23 | font-weight: 400; 24 | src: url("../fonts/Montserrat-Regular.otf") 25 | } 26 | 27 | body { 28 | font-family: 'Montserrat', sans-serif; 29 | /* костиль */ 30 | min-height: calc(100vh + 1px); 31 | } 32 | 33 | *, *:before, *:after { 34 | box-sizing: border-box; 35 | } 36 | 37 | /* Header (logo + navigation) */ 38 | 39 | header { 40 | position: fixed; 41 | top: 0; 42 | width: 100%; 43 | background-color: #44433e; 44 | z-index: 10; 45 | } 46 | 47 | .logo-container { 48 | float: left; 49 | height: 100px; 50 | } 51 | 52 | .logo-container:before { 53 | content: ''; 54 | display: inline-block; 55 | height: 100%; 56 | vertical-align: middle; 57 | } 58 | 59 | .logo-container > a { 60 | text-decoration: none; 61 | } 62 | 63 | .logo-img { 64 | display: inline-block; 65 | vertical-align: middle; 66 | width: 61px; 67 | height: 69px; 68 | margin-right: 5px; 69 | background: url("../img/logo.png") no-repeat; 70 | } 71 | 72 | .logo-text { 73 | display: inline-block; 74 | vertical-align: middle; 75 | font-size: 32px; 76 | text-decoration: none; 77 | } 78 | 79 | .logo-text-part1 { 80 | font-weight: 400; 81 | color: #ffffff; 82 | } 83 | 84 | .logo-text-part2 { 85 | font-weight: bold; 86 | color: #18cfab; 87 | } 88 | 89 | .nav-main { 90 | float: right; 91 | } 92 | 93 | .nav-main > ul { 94 | height: 100px; 95 | margin: 0; 96 | padding: 0; 97 | } 98 | 99 | .nav-main > ul > li { 100 | line-height: 1; 101 | list-style-type: none; 102 | height: 12.5%; 103 | } 104 | 105 | .nav-main > ul > li > a { 106 | display: block; 107 | font-size: 13px; 108 | font-weight: bold; 109 | text-transform: uppercase; 110 | color: #b8b8b8; 111 | text-decoration: none; 112 | cursor: pointer 113 | } 114 | 115 | .nav-main > ul > li > a:hover { 116 | color: #18cfab; 117 | } 118 | 119 | .nav-main > ul > li > a.nav-active { 120 | color: #18cfab; 121 | } 122 | 123 | @media all and (min-width: 768px) { 124 | 125 | .nav-main > ul > li { 126 | float: left; 127 | height: 100%; 128 | } 129 | 130 | .nav-main > ul > li > a:before { 131 | content: ''; 132 | display: inline-block; 133 | height: 100%; 134 | vertical-align: middle; 135 | } 136 | 137 | .nav-main > ul > li > a { 138 | height: 100%; 139 | display: inline-block; 140 | margin: 0 8px; 141 | vertical-align: middle; 142 | border-bottom: 2px solid transparent; 143 | } 144 | 145 | .nav-main > ul > li:first-child > a { 146 | margin-left: 0; 147 | } 148 | 149 | .nav-main > ul > li:last-child > a { 150 | margin-right: 0; 151 | } 152 | 153 | .nav-main > ul > li > a:hover { 154 | border-bottom: 2px solid #18cfab; 155 | transition:all 0.3s; 156 | } 157 | 158 | .nav-main > ul > li > a.nav-active { 159 | border-bottom: 2px solid #18cfab; 160 | } 161 | } 162 | 163 | /*!* Home section (slider + bg image) *!*/ 164 | 165 | .slider-container { 166 | padding-top: 100px; 167 | height: 100vh; 168 | width: 100%; 169 | position: relative; 170 | overflow: hidden; 171 | } 172 | 173 | .slider { 174 | margin: 0; 175 | padding: 0; 176 | height: 100%; 177 | width: 500%; 178 | /*line-height: 0;*/ 179 | } 180 | 181 | .slider-item:before { 182 | content: ''; 183 | display: inline-block; 184 | height: 100%; 185 | vertical-align: middle; 186 | } 187 | 188 | .slider-item { 189 | float: left; 190 | background: url("../img/home-bg1.jpg") no-repeat center; 191 | background: linear-gradient(to bottom, rgba(30, 30, 30, .5) 0%, rgba(30, 30, 30, .5) 100%), url("../img/home-bg1.jpg") no-repeat center; 192 | background-size: cover; 193 | display: inline-block; 194 | width: 20%; 195 | height: 100%; 196 | /*line-height: 1.5;*/ 197 | } 198 | 199 | .slider-content { 200 | display: inline-block; 201 | vertical-align: middle; 202 | width: 100%; 203 | text-align: center; 204 | } 205 | 206 | .slider-text1 { 207 | font-size: 24px; 208 | font-weight: bold; 209 | text-transform: uppercase; 210 | color: white; 211 | margin-bottom: 15px; 212 | } 213 | 214 | .text-highlight { 215 | color: #18cfab; 216 | } 217 | 218 | .slider-text2 { 219 | font-size: 32px; 220 | font-weight: bold; 221 | text-transform: uppercase; 222 | color: white; 223 | margin: 0; 224 | } 225 | 226 | .slider-text3 { 227 | font-size: 20px; 228 | font-weight: lighter; 229 | color: white; 230 | margin: 5px 0; 231 | } 232 | 233 | .slider-nav-container { 234 | position: relative; 235 | } 236 | 237 | .slider-nav-left, .slider-nav-right { 238 | display: inline-block; 239 | width: 60px; 240 | height: 60px; 241 | background-color: #3c4140; 242 | color: #787979; 243 | text-align: center; 244 | padding: 10px; 245 | position: absolute; 246 | z-index: 5; 247 | } 248 | 249 | .slider-nav-left:hover, .slider-nav-right:hover { 250 | background-color: #18cfab; 251 | color: #ffffff; 252 | cursor: pointer; 253 | transition:all 0.5s; 254 | } 255 | 256 | .slider-nav-left { 257 | margin-top: -30px; 258 | top: calc(100vh - 140px); 259 | left: calc(50vw - 120px); 260 | } 261 | 262 | .slider-nav-right { 263 | margin-top: -30px; 264 | top: calc(100vh - 140px); 265 | right: calc(50vw - 120px); 266 | } 267 | 268 | .slider-btn-container { 269 | margin-top: 20px; 270 | text-align: center; 271 | } 272 | 273 | .btn { 274 | display: inline-block; 275 | margin: 10px; 276 | padding: 20px 30px; 277 | font-size: 13px; 278 | font-weight: bold; 279 | color: #ffffff; 280 | background-color: #18cfab; 281 | border: none; 282 | border-radius: 5px; 283 | box-shadow: 0 -5px 0 0 #ffffff; 284 | cursor: pointer; 285 | text-decoration: none; 286 | text-transform: uppercase; 287 | z-index: 1; 288 | } 289 | 290 | .btn:hover { 291 | background-color: #00cbf6; 292 | transition:all 0.5s; 293 | } 294 | 295 | 296 | @media all and (min-width: 687px) { 297 | .slider-text2 { 298 | font-size: 40px; 299 | } 300 | .slider-text3 { 301 | font-size: 26px; 302 | } 303 | .slider-content-container { 304 | padding: 0 60px; 305 | } 306 | .slider-nav-left { 307 | margin-top: -30px; 308 | top: calc(50vh - 50px); 309 | left: -15px; 310 | } 311 | .slider-nav-right { 312 | margin-top: -30px; 313 | top: calc(50vh - 50px); 314 | right: -15px; 315 | } 316 | .slider-btn-container { 317 | margin-top: 70px; 318 | text-align: center; 319 | } 320 | } 321 | 322 | @media all and (min-width: 768px) { 323 | .slider-text2 { 324 | font-size: 60px; 325 | } 326 | .slider-text3 { 327 | font-size: 32px; 328 | } 329 | } 330 | 331 | @media all and (min-width: 992px) { 332 | .slider-text2 { 333 | font-size: 79px; 334 | } 335 | } 336 | 337 | .home-options { 338 | width: 100%; 339 | margin: 0; 340 | padding: 0; 341 | /*line-height: 0;*/ 342 | } 343 | 344 | .home-options-item { 345 | display: inline-block; 346 | float: left; 347 | width: 100%; 348 | height: 300px; 349 | text-align: center; 350 | } 351 | 352 | .home-options-item:nth-child(odd) { 353 | border-top: 7px solid #18cfab; 354 | background-color: #1c2a33; 355 | color: #18cfab; 356 | } 357 | 358 | .home-options-item:nth-child(even) { 359 | border-top: 7px solid #ffffff; 360 | background-color: #18cfab; 361 | color: #ffffff; 362 | } 363 | 364 | .home-options-item:nth-child(1) > .option-item { 365 | background: url("../img/options-icon1.png") no-repeat center; 366 | } 367 | 368 | .home-options-item:nth-child(2) > .option-item { 369 | background: url("../img/options-icon2.png") no-repeat center; 370 | } 371 | 372 | .home-options-item:nth-child(3) > .option-item { 373 | background: url("../img/options-icon3.png") no-repeat center; 374 | } 375 | 376 | .home-options-item:nth-child(4) > .option-item { 377 | background: url("../img/options-icon4.png") no-repeat center; 378 | } 379 | 380 | .option-item { 381 | margin-top: 60px; 382 | margin-bottom: 30px; 383 | height: 100px; 384 | } 385 | 386 | .option-text { 387 | font-size: 20px; 388 | font-weight: 600; 389 | text-transform: uppercase; 390 | } 391 | 392 | @media all and (min-width: 687px) { 393 | .home-options-item { 394 | width: 50%; 395 | } 396 | } 397 | 398 | @media all and (min-width: 992px) { 399 | .home-options-item { 400 | width: 25%; 401 | } 402 | } 403 | 404 | /*!* Services section *!*/ 405 | 406 | .section-offset-top { 407 | padding-top: 30px; 408 | } 409 | 410 | .section-offset-bottom { 411 | padding-bottom: 100px; 412 | } 413 | 414 | .light-bg { 415 | background-color: #ffffff; 416 | } 417 | 418 | .light-bg-tone { 419 | background-color: #f8fcfe; 420 | } 421 | 422 | .dark-bg { 423 | background-color: #090f14; 424 | } 425 | 426 | .dark-bg-tone { 427 | background-color: #22353f; 428 | } 429 | 430 | .dark-bg h1 { 431 | color: #ffffff; 432 | } 433 | 434 | p { 435 | font-size: 14px; 436 | font-weight: 300; 437 | } 438 | 439 | a { 440 | text-decoration: none; 441 | } 442 | 443 | h1 { 444 | font-size: 36px; 445 | font-weight: 400; 446 | margin: 25px 0; 447 | color: #4e4e4e; 448 | } 449 | 450 | .title-content { 451 | padding: 60px 0; 452 | text-align: center; 453 | } 454 | 455 | .title-content > hr { 456 | width: 75px; 457 | height: 1px; 458 | margin: 2px auto; 459 | border: none; 460 | background-color: #18cfab; 461 | position: relative; 462 | } 463 | 464 | .title-content > hr:first-of-type { 465 | left: -5px; 466 | } 467 | 468 | .title-content > hr:last-of-type { 469 | right: -5px; 470 | } 471 | 472 | .service-nav-container { 473 | width: 100%; 474 | } 475 | 476 | .service-nav { 477 | margin: 0 auto; 478 | padding: 0; 479 | text-align: center; 480 | height: 100%; 481 | width: 200px; 482 | } 483 | 484 | .service-nav-item { 485 | height: 100%; 486 | list-style: none; 487 | font-size: 16px; 488 | background-color: #f8f8fb; 489 | border: 1px solid #ebebeb; 490 | } 491 | 492 | .service-nav-item a { 493 | display: block; 494 | color: #717171; 495 | } 496 | 497 | .service-nav-item span { 498 | display: inline-block; 499 | padding: 20px 0; 500 | } 501 | 502 | .service-nav-item.active, .service-nav-item:hover { 503 | background-color: #18cfab; 504 | border: 1px solid #18cfab; 505 | color: #ffffff; 506 | transition:all 0.5s; 507 | } 508 | 509 | @media all and (min-width: 687px) { 510 | .service-nav { 511 | width: 100%; 512 | display:table; 513 | } 514 | .service-nav-item { 515 | display: table-cell; 516 | width: 16.66%; 517 | } 518 | 519 | .service-nav-item.active { 520 | position: relative; 521 | } 522 | 523 | .service-nav-item.active:before { 524 | content: " "; 525 | position: absolute; 526 | left: 50%; 527 | top: 100%; 528 | margin-left: -12px; 529 | border: 12px solid transparent; 530 | border-top-color: #18cfab; 531 | } 532 | 533 | } 534 | 535 | .service-content { 536 | margin-top: 30px; 537 | } 538 | 539 | .service-content-img { 540 | width: 100%; 541 | } 542 | 543 | .service-content-img > img { 544 | width: 100%; 545 | } 546 | 547 | .service-content-text { 548 | width: 100%; 549 | padding-top: 10px; 550 | margin: 0; 551 | text-align: justify; 552 | text-justify: inter-word; 553 | font-size: 14px; 554 | font-weight: 300; 555 | color: #717171; 556 | } 557 | 558 | @media all and (min-width: 687px) { 559 | .service-content-img { 560 | float: left; 561 | width: 16.66%; 562 | } 563 | .service-content-text { 564 | float: right; 565 | width: 83.33%; 566 | padding: 0 0 0 20px; 567 | } 568 | } 569 | 570 | /* About section */ 571 | 572 | .about-container { 573 | text-align: center; 574 | } 575 | 576 | .about-poster { 577 | display: none; 578 | } 579 | 580 | .about-nav { 581 | margin: 0; 582 | padding: 0; 583 | } 584 | 585 | .about-nav-item { 586 | display: inline-block; 587 | padding: 5px 0; 588 | margin-right: 15px; 589 | font-size: 16px; 590 | font-weight: bold; 591 | color: #ffffff; 592 | cursor: pointer; 593 | text-transform: uppercase; 594 | border-top: 2px solid transparent; 595 | } 596 | 597 | .about-nav-item.active, .about-nav-item:hover { 598 | border-top: 2px solid #18cfab; 599 | color: #18cfab; 600 | transition:all 0.5s; 601 | } 602 | 603 | .about-content { 604 | margin: 50px 0; 605 | color: #bebebe; 606 | } 607 | 608 | .skills-diagram-container { 609 | margin: 10px 0; 610 | border: 1px solid grey; 611 | border-radius: 5px; 612 | height: 50px; 613 | /*width: 100%;*/ 614 | text-align: left; 615 | } 616 | 617 | .skills-diagram { 618 | display: inline-block; 619 | background-color: #2d6ca2; 620 | height: 100%; 621 | overflow: hidden; 622 | white-space:nowrap; 623 | line-height: 50px; 624 | padding-left: 20px; 625 | font-size: 16px; 626 | font-weight: 400; 627 | text-transform: uppercase; 628 | color: #ffffff; 629 | transition:all 3s; 630 | } 631 | 632 | .about-content-list { 633 | padding: 0; 634 | margin: 40px 0; 635 | } 636 | 637 | .about-content-list-item { 638 | display: inline-block; 639 | margin: 5px 40px 5px 0; 640 | } 641 | 642 | .about-content-done-text { 643 | display: inline-block; 644 | padding-left: 40px; 645 | background: url("../img/about-done-img.png") no-repeat left; 646 | height: 23px; 647 | } 648 | 649 | @media all and (min-width: 992px) { 650 | .about-poster-container { 651 | padding-left: 0; 652 | } 653 | 654 | .about-poster { 655 | display: block; 656 | width: 100%; 657 | padding: 60px 0; 658 | } 659 | 660 | .about-poster > img { 661 | width: 100%; 662 | } 663 | 664 | .about-container { 665 | text-align: left; 666 | } 667 | 668 | .about-container .title-content { 669 | display: inline-block; 670 | } 671 | } 672 | 673 | /* Work section */ 674 | 675 | .work-nav-container { 676 | text-align: center; 677 | margin-bottom: 50px; 678 | } 679 | 680 | .work-nav { 681 | display: inline-block; 682 | padding: 0; 683 | } 684 | 685 | .work-nav-item { 686 | list-style-type: none; 687 | padding: 15px; 688 | width: 200px; 689 | cursor: pointer; 690 | border: 1px solid #ebebeb; 691 | font-size: 14px; 692 | color: #717171; 693 | text-decoration: none; 694 | } 695 | 696 | .work-nav-item:hover { 697 | color: #18cfab; 698 | transition:all 0.5s; 699 | } 700 | 701 | .work-nav .active { 702 | color: #18cfab; 703 | box-shadow: 0 -2px 0 0 #18cfab; 704 | } 705 | 706 | @media all and (min-width: 687px) { 707 | .work-nav-item { 708 | display: inline-block; 709 | padding: 15px 25px; 710 | width: auto; 711 | } 712 | } 713 | 714 | .work-images { 715 | margin: 0; 716 | padding: 0; 717 | width: 100%; 718 | line-height: 0; 719 | } 720 | 721 | .work-images-item { 722 | display: inline-block; 723 | width: 100%; 724 | position: relative; 725 | } 726 | 727 | .work-images-item > img { 728 | width: 100%; 729 | height: 100%; 730 | } 731 | 732 | .image-mask { 733 | position: absolute; 734 | top: 0; 735 | left: 0; 736 | width: 100%; 737 | height: 100%; 738 | /*height: calc(100% - 4px);*/ 739 | opacity: 0; 740 | text-align: center; 741 | color: #ffffff; 742 | line-height: 1.5; 743 | } 744 | 745 | .image-mask:hover { 746 | opacity: 1; 747 | background-color: rgba(255, 255, 255, 0.85); 748 | box-shadow: inset 0 4px 0 0 #18cfab; 749 | transition:all 0.5s; 750 | } 751 | 752 | .image-mask:before { 753 | content: ''; 754 | display: inline-block; 755 | height: 100%; 756 | vertical-align: middle; 757 | } 758 | 759 | .image-mask-content { 760 | display: inline-block; 761 | vertical-align: middle; 762 | } 763 | 764 | .image-mask-content i{ 765 | width: 42px; 766 | height: 42px; 767 | border: 1px solid #18cfab; 768 | border-radius: 50%; 769 | color: #18cfab; 770 | background-color: #ffffff; 771 | font-size: 16px; 772 | line-height: 40px; 773 | margin: 0 6px; 774 | } 775 | .image-mask-content i:hover{ 776 | background-color: #18cfab; 777 | color: #ffffff; 778 | transition:all 0.5s; 779 | } 780 | 781 | .image-mask-title { 782 | margin: 0; 783 | padding: 20px 0 5px 0; 784 | font-size: 18px; 785 | font-weight: bold; 786 | color: #18cfab; 787 | text-transform: uppercase; 788 | } 789 | 790 | .image-mask-category { 791 | margin: 0; 792 | font-size: 14px; 793 | font-weight: 300; 794 | color: #717171; 795 | } 796 | 797 | @media all and (min-width: 687px) { 798 | 799 | .work-images-item { 800 | width: 50%; 801 | } 802 | } 803 | 804 | @media all and (min-width: 992px) { 805 | 806 | .work-images-item { 807 | width: 33.333%; 808 | } 809 | } 810 | 811 | @media all and (min-width: 1200px) { 812 | 813 | .work-images-item { 814 | width: 25%; 815 | } 816 | } 817 | 818 | /* Team section*/ 819 | 820 | .team-member { 821 | width: 100%; 822 | margin: 20px 0; 823 | text-align: left; 824 | } 825 | 826 | .team-member-photo { 827 | position: relative; 828 | } 829 | 830 | .team-member-photo > img { 831 | width: 100%; 832 | /* Removes image bottom "margin"*/ 833 | vertical-align: middle; 834 | } 835 | 836 | .photo-mask { 837 | position: absolute; 838 | width: 100%; 839 | height: 100%; 840 | top: 0; 841 | background-color: rgba(24, 207, 171, 0.2); 842 | opacity: 0; 843 | } 844 | 845 | .circle { 846 | position: relative; 847 | top: 50%; 848 | border: 2px solid #18cfab; 849 | border-radius: 50%; 850 | width: 80px; 851 | height: 80px; 852 | margin: -40px auto 0 auto; 853 | cursor: pointer; 854 | } 855 | 856 | .photo-mask i { 857 | color: #18cfab; 858 | background-color: #fff; 859 | width: 70px; 860 | height: 70px; 861 | line-height: 72px; 862 | text-align: center; 863 | border-radius: 50%; 864 | margin-top: 3px; 865 | margin-left: 3px; 866 | } 867 | 868 | .team-member-title { 869 | width: 100%; 870 | background-color: #2e4a5b; 871 | } 872 | 873 | .team-member-name { 874 | padding: 10px 0 5px 15px; 875 | margin: 0; 876 | font-size: 16px; 877 | font-weight: bold; 878 | color: #ffffff; 879 | } 880 | 881 | .team-member-position { 882 | padding: 0 0 10px 15px; 883 | margin: 0; 884 | font-size: 13px; 885 | font-weight: 300; 886 | color: #18cfab; 887 | } 888 | 889 | .team-member-links a { 890 | display: inline-block; 891 | float: left; 892 | border-top: 1px solid #ffffff; 893 | border-right: 1px solid #ffffff; 894 | width: 25%; 895 | } 896 | 897 | .team-member-links a:last-child { 898 | border-right: 0; 899 | } 900 | 901 | .team-member-links i { 902 | width: 100%; 903 | height: 65px; 904 | background-color: #2e4a5b; 905 | text-align: center; 906 | line-height: 65px; 907 | color: #ffffff; 908 | } 909 | 910 | .team-member:hover .team-member-title, .team-member:hover .team-member-links i { 911 | background-color: #18cfab; 912 | transition:all 0.5s; 913 | } 914 | 915 | .team-member:hover .team-member-position { 916 | color: #2e4a5b; 917 | transition:all 0.5s; 918 | } 919 | 920 | .team-member:hover .team-member-photo > img { 921 | background-color: rgba(24, 207, 171, 0.5); 922 | } 923 | 924 | .team-member:hover .photo-mask { 925 | opacity: 1; 926 | transition:all 0.5s; 927 | } 928 | 929 | 930 | .team-facts { 931 | width: 100%; 932 | margin: 0; 933 | padding: 0; 934 | } 935 | 936 | .team-facts-item { 937 | display: inline-block; 938 | float: left; 939 | width: 100%; 940 | text-align: center; 941 | border-top: 7px solid #25333c; 942 | background-color: #18cfab; 943 | color: #25333c; 944 | } 945 | 946 | .team-facts-item:nth-child(odd) { 947 | border-top: 7px solid #18cfab; 948 | background-color: #25333c; 949 | color: #18cfab; 950 | } 951 | 952 | .fact-circle { 953 | border: 2px solid #25333c; 954 | border-radius: 50%; 955 | width: 165px; 956 | height: 165px; 957 | margin: 50px auto 0; 958 | } 959 | 960 | .team-facts-item:nth-child(odd) .fact-circle { 961 | border: 2px solid #18cfab; 962 | } 963 | 964 | .fact-circle i { 965 | color: #ffffff; 966 | background-color: #25333c; 967 | width: 100px; 968 | height: 100px; 969 | line-height: 100px; 970 | text-align: center; 971 | border-radius: 50%; 972 | margin-top: 30px; 973 | } 974 | 975 | .team-facts-item:nth-child(odd) .fact-circle i { 976 | background-color: #18cfab; 977 | } 978 | 979 | .fact-number { 980 | font-size: 36px; 981 | font-weight: 400; 982 | color: #ffffff; 983 | margin: 20px auto 5px auto; 984 | } 985 | 986 | .fact-title { 987 | font-size: 18px; 988 | font-weight: 300; 989 | color: #25333c; 990 | margin: 0 auto 30px auto; 991 | } 992 | 993 | .team-facts-item:nth-child(odd) .fact-title { 994 | color: #18cfab; 995 | } 996 | 997 | @media all and (min-width: 687px) { 998 | .team-facts-item { 999 | width: 50%; 1000 | } 1001 | } 1002 | 1003 | @media all and (min-width: 992px) { 1004 | .team-facts-item { 1005 | width: 25%; 1006 | } 1007 | } 1008 | 1009 | 1010 | /* News section */ 1011 | 1012 | .news-container { 1013 | margin-bottom: 30px; 1014 | /*cursor: pointer;*/ 1015 | } 1016 | 1017 | .news-photo-container { 1018 | position: relative; 1019 | } 1020 | 1021 | .news-photo-container img { 1022 | width: 100%; 1023 | /* Removes image bottom "margin"*/ 1024 | vertical-align: middle; 1025 | } 1026 | 1027 | .news-date { 1028 | display: inline-block; 1029 | position: absolute; 1030 | width: 60px; 1031 | height: 60px; 1032 | top: 0; 1033 | right: 0; 1034 | color: #ffffff; 1035 | background-color: #203e38; 1036 | padding: 10px; 1037 | text-align: center; 1038 | } 1039 | 1040 | .news-title { 1041 | padding: 20px 0; 1042 | margin: 0; 1043 | border: 1px solid #c2c2c2; 1044 | font-size: 18px; 1045 | font-weight: bold; 1046 | color: #717171; 1047 | background-color: #f8fcfe; 1048 | text-align: center; 1049 | } 1050 | 1051 | .news-container:hover .news-date { 1052 | background-color: #18cfab; 1053 | transition:all 0.5s; 1054 | } 1055 | 1056 | .news-container:hover .news-title { 1057 | color: #18cfab; 1058 | transition:all 0.5s; 1059 | } 1060 | 1061 | .news-btn-container { 1062 | text-align: center; 1063 | } 1064 | 1065 | .news-load-btn { 1066 | margin-top: 40px; 1067 | line-height: 18px; 1068 | } 1069 | 1070 | .news-load-btn i { 1071 | vertical-align: middle; 1072 | font-size: 18px; 1073 | margin-right: 15px; 1074 | } 1075 | 1076 | 1077 | /* Contact section */ 1078 | 1079 | .feedback-container { 1080 | width: 100%; 1081 | padding: 30px; 1082 | border: 3px solid #c2c2c2; 1083 | background-color: #ffffff; 1084 | min-height: 500px; 1085 | } 1086 | 1087 | .feedback-item { 1088 | margin-bottom: 30px; 1089 | position: relative; 1090 | width: 100%; 1091 | border: 1px solid #c2c2c2; 1092 | border-radius: 5px; 1093 | } 1094 | 1095 | .feedback-item:last-child { 1096 | margin-bottom: 0; 1097 | } 1098 | 1099 | .feedback-item-title { 1100 | margin: 0; 1101 | padding: 10px 15px; 1102 | font-size: 18px; 1103 | color: #4e4e4e; 1104 | background-color: #f7f7f7; 1105 | } 1106 | 1107 | .feedback-item-text { 1108 | margin: 0; 1109 | padding: 15px; 1110 | font-size: 14px; 1111 | font-weight: 300; 1112 | color: #4e4e4e; 1113 | } 1114 | 1115 | .feedback-item-remove { 1116 | position: absolute; 1117 | top: 10px; 1118 | right: 15px; 1119 | cursor: pointer; 1120 | } 1121 | 1122 | .feedback-add-form { 1123 | margin-top: 70px; 1124 | margin-bottom: 100px; 1125 | } 1126 | 1127 | .feedback-add-form input { 1128 | height: 70px; 1129 | } 1130 | 1131 | .feedback-add-form textarea { 1132 | height: 120px; 1133 | } 1134 | 1135 | .feedback-add-form input, .feedback-add-form textarea { 1136 | display: block; 1137 | border: 1px solid #efeff1; 1138 | margin: 10px 0; 1139 | width: 100%; 1140 | font-size: 24px; 1141 | font-weight: 300; 1142 | color: #4e4e4e; 1143 | padding: 15px; 1144 | } 1145 | 1146 | .feedback-add-btn { 1147 | margin: 0; 1148 | line-height: 18px; 1149 | } 1150 | 1151 | .feedback-add-btn i { 1152 | vertical-align: middle; 1153 | font-size: 18px; 1154 | margin-right: 15px; 1155 | } 1156 | 1157 | .feedback-btn-container { 1158 | text-align: center; 1159 | } 1160 | 1161 | @media all and (min-width: 768px) { 1162 | .feedback-btn-container { 1163 | text-align: left; 1164 | } 1165 | } 1166 | 1167 | /****************************/ 1168 | 1169 | .contact-container { 1170 | margin-top: 100px; 1171 | margin-bottom: 100px; 1172 | } 1173 | 1174 | .contact-container .title-content { 1175 | padding-top: 0;; 1176 | } 1177 | 1178 | .map-container { 1179 | padding: 0; 1180 | } 1181 | 1182 | @media all and (min-width: 768px) { 1183 | .contact-container .title-content { 1184 | display: inline-block; 1185 | } 1186 | .map-container { 1187 | padding: 0 15px 0 0; 1188 | } 1189 | } 1190 | 1191 | .contact-form input { 1192 | height: 50px; 1193 | } 1194 | 1195 | .contact-form textarea { 1196 | height: 180px; 1197 | } 1198 | 1199 | .contact-form input, .contact-form textarea { 1200 | display: block; 1201 | border: 1px solid #efeff1; 1202 | margin: 10px 0; 1203 | width: 100%; 1204 | font-size: 14px; 1205 | font-weight: 300; 1206 | color: #4e4e4e; 1207 | padding: 15px; 1208 | } 1209 | 1210 | .contact-form-btn { 1211 | display: block; 1212 | width: 100%; 1213 | text-align: center; 1214 | margin: 0; 1215 | box-shadow: inset 0 -5px 0 0 #08bf9b; 1216 | } 1217 | 1218 | .contact-form .error { 1219 | font-size: 14px; 1220 | color: red; 1221 | } 1222 | 1223 | /*!* Footer *!*/ 1224 | 1225 | .footer-container { 1226 | padding-top: 20px; 1227 | padding-bottom: 20px; 1228 | vertical-align: middle; 1229 | text-align: center; 1230 | } 1231 | 1232 | .footer-container:before { 1233 | content: ''; 1234 | display: inline-block; 1235 | height: 100%; 1236 | vertical-align: middle; 1237 | } 1238 | 1239 | .footer-text { 1240 | display: inline-block; 1241 | vertical-align: middle; 1242 | text-align: center; 1243 | font-size: 14px; 1244 | font-weight: 300; 1245 | color: #aeaeae; 1246 | } 1247 | 1248 | .footer-btn { 1249 | display: inline-block; 1250 | vertical-align: middle; 1251 | width: 45px; 1252 | height: 45px; 1253 | background-color: #18cfab; 1254 | margin: 20px; 1255 | line-height: 42px; 1256 | cursor: pointer; 1257 | } 1258 | 1259 | .footer-btn:hover { 1260 | background-color: #00cbf6; 1261 | transition:all 0.5s; 1262 | } 1263 | 1264 | .footer-btn i { 1265 | color: white; 1266 | font-size: 35px; 1267 | vertical-align: middle; 1268 | } -------------------------------------------------------------------------------- /data/data.json: -------------------------------------------------------------------------------- 1 | [{"id":1,"date":"3/5/2016","text":"Ut at dolor quis odio consequat varius. Integer ac leo. Pellentesque ultrices mattis odio. Donec vitae nisi. Nam ultrices, libero non mattis pulvinar, nulla pede ullamcorper augue, a suscipit nulla elit ac nulla. Sed vel enim sit amet nunc viverra dapibus. Nulla suscipit ligula in lacus. Curabitur at ipsum ac tellus semper interdum. Mauris ullamcorper purus sit amet nulla. Quisque arcu libero, rutrum ac, lobortis vel, dapibus at, diam."}, 2 | {"id":2,"date":"1/16/2016","text":"Integer ac leo. Pellentesque ultrices mattis odio. Donec vitae nisi. Nam ultrices, libero non mattis pulvinar, nulla pede ullamcorper augue, a suscipit nulla elit ac nulla. Sed vel enim sit amet nunc viverra dapibus. Nulla suscipit ligula in lacus."}, 3 | {"id":3,"date":"7/24/2016","text":"Suspendisse potenti. Nullam porttitor lacus at turpis. Donec posuere metus vitae ipsum. Aliquam non mauris. Morbi non lectus. Aliquam sit amet diam in magna bibendum imperdiet. Nullam orci pede, venenatis non, sodales sed, tincidunt eu, felis. Fusce posuere felis sed lacus. Morbi sem mauris, laoreet ut, rhoncus aliquet, pulvinar sed, nisl. Nunc rhoncus dui vel sem."}, 4 | {"id":4,"date":"8/4/2016","text":"Proin eu mi. Nulla ac enim. In tempor, turpis nec euismod scelerisque, quam turpis adipiscing lorem, vitae mattis nibh ligula nec sem. Duis aliquam convallis nunc. Proin at turpis a pede posuere nonummy. Integer non velit. Donec diam neque, vestibulum eget, vulputate ut, ultrices vel, augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec pharetra, magna vestibulum aliquet ultrices, erat tortor sollicitudin mi, sit amet lobortis sapien sapien non mi."}, 5 | {"id":5,"date":"3/26/2016","text":"Duis bibendum. Morbi non quam nec dui luctus rutrum. Nulla tellus. In sagittis dui vel nisl. Duis ac nibh. Fusce lacus purus, aliquet at, feugiat non, pretium quis, lectus. Suspendisse potenti. In eleifend quam a odio."}, 6 | {"id":6,"date":"8/4/2016","text":"Nullam sit amet turpis elementum ligula vehicula consequat. Morbi a ipsum. Integer a nibh. In quis justo. Maecenas rhoncus aliquam lacus. Morbi quis tortor id nulla ultrices aliquet. Maecenas leo odio, condimentum id, luctus nec, molestie sed, justo. Pellentesque viverra pede ac diam. Cras pellentesque volutpat dui. Maecenas tristique, est et tempus semper, est quam pharetra magna, ac consequat metus sapien ut nunc."}, 7 | {"id":7,"date":"8/11/2016","text":"Donec posuere metus vitae ipsum. Aliquam non mauris. Morbi non lectus. Aliquam sit amet diam in magna bibendum imperdiet. Nullam orci pede, venenatis non, sodales sed, tincidunt eu, felis. Fusce posuere felis sed lacus. Morbi sem mauris, laoreet ut, rhoncus aliquet, pulvinar sed, nisl."}, 8 | {"id":8,"date":"7/14/2016","text":"Integer a nibh. In quis justo. Maecenas rhoncus aliquam lacus. Morbi quis tortor id nulla ultrices aliquet. Maecenas leo odio, condimentum id, luctus nec, molestie sed, justo. Pellentesque viverra pede ac diam."}, 9 | {"id":9,"date":"3/5/2016","text":"Nam dui. Proin leo odio, porttitor id, consequat in, consequat ut, nulla. Sed accumsan felis. Ut at dolor quis odio consequat varius. Integer ac leo. Pellentesque ultrices mattis odio. Donec vitae nisi. Nam ultrices, libero non mattis pulvinar, nulla pede ullamcorper augue, a suscipit nulla elit ac nulla. Sed vel enim sit amet nunc viverra dapibus. Nulla suscipit ligula in lacus."}, 10 | {"id":10,"date":"2/12/2016","text":"Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam vel augue. Vestibulum rutrum rutrum neque. Aenean auctor gravida sem. Praesent id massa id nisl venenatis lacinia. Aenean sit amet justo. Morbi ut odio. Cras mi pede, malesuada in, imperdiet et, commodo vulputate, justo. In blandit ultrices enim."}, 11 | {"id":11,"date":"2/15/2016","text":"Aenean auctor gravida sem. Praesent id massa id nisl venenatis lacinia. Aenean sit amet justo. Morbi ut odio. Cras mi pede, malesuada in, imperdiet et, commodo vulputate, justo. In blandit ultrices enim."}, 12 | {"id":12,"date":"2/26/2016","text":"Sed accumsan felis. Ut at dolor quis odio consequat varius. Integer ac leo. Pellentesque ultrices mattis odio. Donec vitae nisi. Nam ultrices, libero non mattis pulvinar, nulla pede ullamcorper augue, a suscipit nulla elit ac nulla. Sed vel enim sit amet nunc viverra dapibus. Nulla suscipit ligula in lacus."}, 13 | {"id":13,"date":"7/27/2016","text":"Proin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue. Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl. Aenean lectus. Pellentesque eget nunc. Donec quis orci eget orci vehicula condimentum."}, 14 | {"id":14,"date":"2/19/2016","text":"Cras mi pede, malesuada in, imperdiet et, commodo vulputate, justo. In blandit ultrices enim. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue. Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl."}, 15 | {"id":15,"date":"2/26/2016","text":"Praesent blandit lacinia erat. Vestibulum sed magna at nunc commodo placerat. Praesent blandit. Nam nulla. Integer pede justo, lacinia eget, tincidunt eget, tempus vel, pede. Morbi porttitor lorem id ligula. Suspendisse ornare consequat lectus. In est risus, auctor sed, tristique in, tempus sit amet, sem. Fusce consequat. Nulla nisl."}, 16 | {"id":16,"date":"6/8/2016","text":"Pellentesque at nulla. Suspendisse potenti. Cras in purus eu magna vulputate luctus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus vestibulum sagittis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam vel augue."}, 17 | {"id":17,"date":"4/6/2016","text":"Mauris lacinia sapien quis libero. Nullam sit amet turpis elementum ligula vehicula consequat. Morbi a ipsum. Integer a nibh. In quis justo."}, 18 | {"id":18,"date":"9/2/2016","text":"Nulla suscipit ligula in lacus. Curabitur at ipsum ac tellus semper interdum. Mauris ullamcorper purus sit amet nulla. Quisque arcu libero, rutrum ac, lobortis vel, dapibus at, diam. Nam tristique tortor eu pede."}, 19 | {"id":19,"date":"5/26/2016","text":"Donec quis orci eget orci vehicula condimentum. Curabitur in libero ut massa volutpat convallis. Morbi odio odio, elementum eu, interdum eu, tincidunt in, leo. Maecenas pulvinar lobortis est. Phasellus sit amet erat. Nulla tempus. Vivamus in felis eu sapien cursus vestibulum."}, 20 | {"id":20,"date":"4/24/2016","text":"In eleifend quam a odio. In hac habitasse platea dictumst. Maecenas ut massa quis augue luctus tincidunt. Nulla mollis molestie lorem. Quisque ut erat. Curabitur gravida nisi at nibh."}] -------------------------------------------------------------------------------- /fonts/Montserrat-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/fonts/Montserrat-Bold.otf -------------------------------------------------------------------------------- /fonts/Montserrat-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/fonts/Montserrat-Light.otf -------------------------------------------------------------------------------- /fonts/Montserrat-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/fonts/Montserrat-Regular.otf -------------------------------------------------------------------------------- /fonts/Montserrat-SemiBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/fonts/Montserrat-SemiBold.otf -------------------------------------------------------------------------------- /img/about-done-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/about-done-img.png -------------------------------------------------------------------------------- /img/about-img.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/about-img.jpeg -------------------------------------------------------------------------------- /img/home-bg1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/home-bg1.jpg -------------------------------------------------------------------------------- /img/home-bg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/home-bg2.jpg -------------------------------------------------------------------------------- /img/home-bg3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/home-bg3.jpg -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/logo.png -------------------------------------------------------------------------------- /img/news-img1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/news-img1.jpeg -------------------------------------------------------------------------------- /img/options-icon1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/options-icon1.png -------------------------------------------------------------------------------- /img/options-icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/options-icon2.png -------------------------------------------------------------------------------- /img/options-icon3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/options-icon3.png -------------------------------------------------------------------------------- /img/options-icon4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/options-icon4.png -------------------------------------------------------------------------------- /img/service-img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/service-img1.jpg -------------------------------------------------------------------------------- /img/service-img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/service-img2.jpg -------------------------------------------------------------------------------- /img/social-hover-icon1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/social-hover-icon1.png -------------------------------------------------------------------------------- /img/social-hover-icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/social-hover-icon2.png -------------------------------------------------------------------------------- /img/social-hover-icon3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/social-hover-icon3.png -------------------------------------------------------------------------------- /img/social-hover-icon4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/social-hover-icon4.png -------------------------------------------------------------------------------- /img/social-icon1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/social-icon1.png -------------------------------------------------------------------------------- /img/social-icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/social-icon2.png -------------------------------------------------------------------------------- /img/social-icon3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/social-icon3.png -------------------------------------------------------------------------------- /img/social-icon4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/social-icon4.png -------------------------------------------------------------------------------- /img/team_member1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/team_member1.jpg -------------------------------------------------------------------------------- /img/work-img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/work-img1.jpg -------------------------------------------------------------------------------- /img/work-img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/work-img2.jpg -------------------------------------------------------------------------------- /img/work-img3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/work-img3.jpg -------------------------------------------------------------------------------- /img/work-img4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/work-img4.jpg -------------------------------------------------------------------------------- /img/work-img5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/work-img5.jpg -------------------------------------------------------------------------------- /img/work-img6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozadev/project-react-landing/7b338f44f2e3b36ad3c058b22eb685b8c3beb37a/img/work-img6.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ReactJS project (theHam template) 6 | 7 | 8 | 9 | 10 | 11 | 13 | 15 | 16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /js/src/actions/aboutActions.js: -------------------------------------------------------------------------------- 1 |  2 | export const showView = (number) => { 3 | return { 4 | type: 'CHANGE_VIEW', 5 | payload: number 6 | } 7 | }; 8 | 9 | export const showSkillsEnable = () => { 10 | return { 11 | type: 'SHOW_SKILLS' 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /js/src/actions/contactFormActions.js: -------------------------------------------------------------------------------- 1 |  2 | export const changeFieldValue = (newFieldVal) => { 3 | return { 4 | type: 'FIELD_CHANGE', 5 | payload: newFieldVal 6 | } 7 | }; 8 | 9 | -------------------------------------------------------------------------------- /js/src/actions/feedbackActions.js: -------------------------------------------------------------------------------- 1 |  2 | export const addComment = (data) => { 3 | return { 4 | type: 'ADD_COMMENT', 5 | payload: data 6 | } 7 | }; 8 | 9 | export const removeComment = (id) => { 10 | return { 11 | type: 'REMOVE_COMMENT', 12 | payload: id 13 | } 14 | }; 15 | 16 | export const initComments = (data) => { 17 | return { 18 | type: 'INIT_COMMENTS', 19 | payload: data 20 | } 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /js/src/actions/newsActions.js: -------------------------------------------------------------------------------- 1 |  2 | export const showMore = () => { 3 | return { 4 | type: 'SHOW_MORE' 5 | } 6 | }; 7 | 8 | export const requestUsers = () => { 9 | return { 10 | type: 'FETCH_DATA_START', 11 | } 12 | }; 13 | 14 | export const fetchError = () => { 15 | return { 16 | type: 'FETCH_DATA_ERROR', 17 | } 18 | }; 19 | 20 | export const receiveUsers = (users) => { 21 | return { 22 | type: 'RECEIVE_DATA', 23 | payload: users 24 | } 25 | }; 26 | 27 | export function fetchUsers(path) { 28 | return function(dispatch) { 29 | dispatch(requestUsers()); 30 | 31 | return ( 32 | fetch(path) 33 | .then(response => response.json()) 34 | .then(json => dispatch(receiveUsers(json))) 35 | .catch(() => dispatch(fetchError())) 36 | ) 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /js/src/actions/portfolioActions.js: -------------------------------------------------------------------------------- 1 |  2 | export const changeLink = (number) => { 3 | return { 4 | type: 'CHANGE_LINK', 5 | payload: number 6 | } 7 | }; 8 | 9 | -------------------------------------------------------------------------------- /js/src/actions/sliderActions.js: -------------------------------------------------------------------------------- 1 | let switchAutoTimerId; 2 | let switchAutoEnableTimerId; 3 | 4 | 5 | export const switchToSlide = (direction) => { 6 | if (switchAutoTimerId) { 7 | clearInterval(switchAutoTimerId); 8 | switchAutoTimerId = undefined; 9 | } 10 | if (switchAutoEnableTimerId) { 11 | clearTimeout(switchAutoEnableTimerId); 12 | switchAutoEnableTimerId = undefined; 13 | } 14 | 15 | return { 16 | type: 'CHANGE_SLIDE', 17 | payload: direction 18 | } 19 | }; 20 | 21 | export const switchTimeoutHidden = (time) => { 22 | return function(dispatch) { 23 | setTimeout(() => { 24 | dispatch({type: 'CHANGE_SLIDE_HIDDEN'}); 25 | }, time) 26 | } 27 | }; 28 | 29 | export const switchAuto = () => { 30 | return function(dispatch) { 31 | if (switchAutoTimerId !== undefined) { 32 | return; 33 | } 34 | switchAutoTimerId = setInterval(() => { 35 | dispatch({type: 'CHANGE_SLIDE', payload: 'next'}); 36 | }, 3000) 37 | } 38 | }; 39 | 40 | export const switchAutoEnable = () => { 41 | return function(dispatch) { 42 | if (switchAutoEnableTimerId !== undefined) { 43 | return; 44 | } 45 | switchAutoEnableTimerId = setTimeout(() => { 46 | dispatch(switchAuto()); 47 | }, 2000); 48 | // 2s + 3s (for slide change) ==> 5s delay 49 | } 50 | }; 51 | 52 | 53 | -------------------------------------------------------------------------------- /js/src/actions/teamFactsActions.js: -------------------------------------------------------------------------------- 1 | let countTimerId; 2 | 3 | export const initOptions = (data) => { 4 | return { 5 | type: 'INIT', 6 | payload: data 7 | } 8 | }; 9 | 10 | export const startCount = (time) => { 11 | return function(dispatch) { 12 | if (countTimerId !== undefined) { 13 | return; 14 | } 15 | countTimerId = setInterval(() => { 16 | dispatch({type: 'NEXT_VAL'}); 17 | }, time) 18 | } 19 | }; 20 | 21 | export const stopCount = () => { 22 | return function(dispatch) { 23 | if (countTimerId) { 24 | clearInterval(countTimerId); 25 | countTimerId = undefined; 26 | } 27 | dispatch({type: 'FINISHED'}); 28 | } 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /js/src/components/aboutSection/biographyBlock.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class BiographyBlock extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | render() { 8 | return ( 9 |
10 |

Lorem ipsum dolor sit amet, adipisci repudiare sed et, aperiri feugiat id vel, ridens animal aliquando vis ut. Te est tollit disputationi, at mei habeo summo. Percipit oportere reprehendunt per ut, no solum ludus meliore vix. Cu eos explicari repudiare. Harum verear quaeque et pri, ei rebum maiorum intellegam usu. Inani possit neglegentur id vel.

11 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum quis mauris interdum, blandit nulla at, bibendum velit. Donec tristique, tortor cursus posuere aliquam

12 |
13 | ); 14 | } 15 | } 16 | 17 | 18 | export default BiographyBlock; -------------------------------------------------------------------------------- /js/src/components/aboutSection/historyBlock.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class HistoryBlock extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | render() { 8 | return ( 9 |
10 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum quis mauris interdum, blandit nulla at, bibendum velit. Donec tristique, tortor cursus posuere aliquam

11 | 21 |
22 | ); 23 | } 24 | } 25 | 26 | 27 | export default HistoryBlock; -------------------------------------------------------------------------------- /js/src/components/aboutSection/skillsBlock.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | let data = [ 4 | {text: 'User interface', width: '75%', backgroundColor: '#9c5da5'}, 5 | {text: 'Web design', width: '85%', backgroundColor: '#11b0de'}, 6 | {text: 'Wordpress', width: '70%', backgroundColor: '#d67f7f'}, 7 | {text: 'HTML & CSS', width: '90%', backgroundColor: '#20bc9d'}, 8 | {text: 'App design', width: '85%', backgroundColor: '#bb8a36'} 9 | ]; 10 | 11 | class SkillsBlock extends React.Component { 12 | constructor(props) { 13 | super(props); 14 | } 15 | 16 | render() { 17 | 18 | let items = data.map((item, index) => { 19 | return ( 20 |
21 |
24 | {item.text} 25 |
26 |
27 | ); 28 | }); 29 | 30 | return ( 31 |
32 | {items} 33 |
34 | ); 35 | } 36 | } 37 | 38 | export default SkillsBlock; -------------------------------------------------------------------------------- /js/src/components/feedbackItem.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class FeedbackItem extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | render() { 8 | return ( 9 |
10 |

{this.props.title}

11 |

{this.props.message}

12 | 13 | 14 | 15 |
16 | ); 17 | } 18 | } 19 | 20 | export default FeedbackItem; -------------------------------------------------------------------------------- /js/src/components/newsItem.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router'; 3 | 4 | class NewsItem extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | } 8 | render() { 9 | return ( 10 |
11 | 12 |
13 | 14 | {this.props.date} 15 |
16 |

{this.props.title}

17 | 18 |
19 | ); 20 | } 21 | } 22 | 23 | export default NewsItem; -------------------------------------------------------------------------------- /js/src/components/portfolioItem.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class PortfolioItem extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | render() { 8 | return ( 9 |
  • 10 | 11 |
    12 | 13 | 14 | 15 | 16 | 17 |

    {this.props.title}

    18 |

    {this.props.category}

    19 |
    20 |
    21 |
  • 22 | ); 23 | } 24 | } 25 | 26 | export default PortfolioItem; -------------------------------------------------------------------------------- /js/src/components/serviceSection/ServiceItems.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export class ServiceWeb extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | render() { 8 | return ( 9 |
    10 |
    11 | 12 |
    13 |

    Et quot utroque oportere vel, est doctus lobortis ut. Doming consequuntur sed ut, iudico ridens utroque ne sed, usu quis suavitate ea. Ne dico nullam deseruisse vix, posse definitiones usu ex. Option ponderum laboramus cum te, te vel munere intellegam. Animal pertinacia sit at, ne fierent appetere suavitate mei.

    14 |
    15 | ) 16 | } 17 | } 18 | 19 | export class ServiceGraphic extends React.Component { 20 | constructor(props) { 21 | super(props); 22 | } 23 | render() { 24 | return ( 25 |
    26 |
    27 | 28 |
    29 |

    Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Vivamus suscipit tortor eget felis porttitor volutpat. Curabitur aliquet quam id dui posuere blandit. Nulla porttitor accumsan tincidunt. Cras ultricies ligula sed magna dictum porta. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Vivamus suscipit tortor eget felis porttitor volutpat. Curabitur aliquet quam id dui posuere blandit. Nulla porttitor accumsan tincidunt. Cras ultricies ligula sed magna dictum porta.

    30 |
    31 | ) 32 | } 33 | } 34 | 35 | export class ServiceSupport extends React.Component { 36 | constructor(props) { 37 | super(props); 38 | } 39 | render() { 40 | return ( 41 |
    42 |
    43 | 44 |
    45 |

    Vivamus suscipit tortor eget felis porttitor volutpat. Curabitur aliquet quam id dui posuere blandit. Nulla porttitor accumsan tincidunt. Cras ultricies ligula sed magna dictum porta. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Vivamus suscipit tortor eget felis porttitor volutpat. Curabitur aliquet quam id dui posuere blandit. Nulla porttitor accumsan tincidunt. Cras ultricies ligula sed magna dictum porta. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus.

    46 |
    47 | ) 48 | } 49 | } 50 | 51 | export class ServiceApp extends React.Component { 52 | constructor(props) { 53 | super(props); 54 | } 55 | render() { 56 | return ( 57 |
    58 |
    59 | 60 |
    61 |

    Lorem ipsum dolor sit amet, id pro dicunt audire probatus, no doming menandri torquatos eum, no cum natum mandamus. Pro at graeci salutatus. Amet munere honestatis per ad, causae meliore percipitur no his. An eos minimum assentior scriptorem. Ad exerci volumus efficiantur usu, duo no facete constituam conclusionemque, menandri pertinacia sententiae vim no.

    62 |
    63 | ) 64 | } 65 | } 66 | 67 | 68 | export class ServiceMarketing extends React.Component { 69 | constructor(props) { 70 | super(props); 71 | } 72 | render() { 73 | return ( 74 |
    75 |
    76 | 77 |
    78 |

    Mentitum qualisque ex sed, qui quaeque docendi interpretaris in. Ut duo possim vocent liberavisse, sale commodo ex cum, tollit delicata reprimique pri ut. Alienum deseruisse dissentiunt et has, nobis consequuntur mel ea, at ludus oratio noster vim. Id eum nominavi assueverit, error eloquentiam qui no, id est dicant quaeque. Affert consetetur pri id, sed nullam ridens facilis ne, congue labores scripserit ut sit.

    79 |
    80 | ) 81 | } 82 | } 83 | 84 | export class ServiceSeo extends React.Component { 85 | constructor(props) { 86 | super(props); 87 | } 88 | render() { 89 | return ( 90 |
    91 |
    92 | 93 |
    94 |

    Habeo apeirian eos et. Dicant molestie in mel. Cu mea epicurei evertitur. Mucius definitionem ad vim, vim rebum accusam epicuri et. Mel rebum dignissim mediocritatem te, amet case erat his no, mei ne dolore hendrerit. Quo no doctus detracto reformidans.

    95 |
    96 | ) 97 | } 98 | } -------------------------------------------------------------------------------- /js/src/components/slider/sliderItem1.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link as ScrollLink } from 'react-scroll'; 3 | 4 | class SliderItem1 extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | } 8 | render() { 9 | 10 | let scrollOptions = { 11 | duration: 1000, 12 | offset: -100, 13 | smooth: true, 14 | spy: true 15 | }; 16 | 17 | let sliderItemBg = { 18 | background: 'linear-gradient(to bottom, rgba(30, 30, 30, .5) 0%, rgba(30, 30, 30, .5) 100%), url("./img/home-bg1.jpg") no-repeat center', 19 | backgroundSize: 'cover' 20 | }; 21 | 22 | return ( 23 |
  • 24 |
    25 |
    26 |

    #1 The ham is a psd template

    27 |

    We are creative

    28 |

    Nam varius accumsan elementum aliquam

    29 |
    30 | Explore now 31 | Purchase now 32 |
    33 |
    34 |
    35 |
  • 36 | ) 37 | } 38 | } 39 | 40 | 41 | export default SliderItem1; -------------------------------------------------------------------------------- /js/src/components/slider/sliderItem2.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link as ScrollLink } from 'react-scroll'; 3 | 4 | class SliderItem2 extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | } 8 | render() { 9 | 10 | let scrollOptions = { 11 | duration: 1000, 12 | offset: -100, 13 | smooth: true, 14 | spy: true 15 | }; 16 | 17 | let sliderItemBg = { 18 | background: 'linear-gradient(to bottom, rgba(30, 30, 30, .5) 0%, rgba(30, 30, 30, .5) 100%), url("./img/home-bg2.jpg") no-repeat center', 19 | backgroundSize: 'cover' 20 | }; 21 | 22 | return ( 23 |
  • 24 |
    25 |
    26 |

    #2 The ham is a psd template

    27 |

    We are fast

    28 |

    Lorem ipsum dolor sit amet, his ea.

    29 |
    30 | Explore now 31 | Purchase now 32 |
    33 |
    34 |
    35 |
  • 36 | ) 37 | } 38 | } 39 | 40 | 41 | export default SliderItem2; -------------------------------------------------------------------------------- /js/src/components/slider/sliderItem3.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link as ScrollLink } from 'react-scroll'; 3 | 4 | class SliderItem3 extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | } 8 | render() { 9 | 10 | let scrollOptions = { 11 | duration: 1000, 12 | offset: -100, 13 | smooth: true, 14 | spy: true 15 | }; 16 | 17 | let sliderItemBg = { 18 | background: 'linear-gradient(to bottom, rgba(30, 30, 30, .5) 0%, rgba(30, 30, 30, .5) 100%), url("./img/home-bg3.jpg") no-repeat center', 19 | backgroundSize: 'cover' 20 | }; 21 | 22 | return ( 23 |
  • 24 |
    25 |
    26 |

    #3 The ham is a psd template

    27 |

    We are professionals

    28 |

    Zril mandamus eos ne, sed audire facilisis ex

    29 |
    30 | Explore now 31 | Purchase now 32 |
    33 |
    34 |
    35 |
  • 36 | ) 37 | } 38 | } 39 | 40 | 41 | export default SliderItem3; -------------------------------------------------------------------------------- /js/src/components/teamFactsItem.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class TeamFactsItem extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | render() { 8 | return ( 9 |
  • 10 |
    11 | {this.props.favicon} 12 |
    13 |

    {this.props.number}

    14 |

    {this.props.title}

    15 |
  • 16 | ) 17 | } 18 | } 19 | 20 | export default TeamFactsItem; -------------------------------------------------------------------------------- /js/src/components/teamMember.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class TeamMember extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | render() { 8 | return ( 9 |
    10 |
    11 |
    12 | 13 |
    14 |
    15 | 16 |
    17 |
    18 |
    19 |
    20 |

    {this.props.name}

    21 |

    {this.props.position}

    22 |
    23 |
    24 | 25 | 26 | 27 | 28 |
    29 |
    30 |
    31 | ); 32 | } 33 | } 34 | 35 | export default TeamMember; -------------------------------------------------------------------------------- /js/src/containers/aboutApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { bindActionCreators } from 'redux'; 3 | import { connect } from 'react-redux'; 4 | 5 | import SkillsBlock from '../components/aboutSection/skillsBlock.jsx'; 6 | import BiographyBlock from '../components/aboutSection/biographyBlock.jsx'; 7 | import HistoryBlock from '../components/aboutSection/historyBlock.jsx'; 8 | 9 | import * as actions from '../actions/aboutActions.js'; 10 | 11 | 12 | class AboutApp extends React.Component { 13 | constructor(props) { 14 | super(props); 15 | 16 | this.scrollHandler = this.scrollHandler.bind(this); 17 | } 18 | 19 | componentDidMount() { 20 | document.addEventListener('scroll', this.scrollHandler); 21 | } 22 | 23 | componentWillUnmount() { 24 | document.removeEventListener('scroll', this.scrollHandler); 25 | } 26 | 27 | scrollHandler(e) { 28 | let top = document.querySelector('#about-block').getBoundingClientRect().top; 29 | let bottom = document.querySelector('#about-block').getBoundingClientRect().bottom; 30 | let headerOffset = 100; 31 | 32 | if (top <= document.documentElement.clientHeight && bottom >= headerOffset) { 33 | document.removeEventListener('scroll', this.scrollHandler); 34 | this.props.showSkillsEnable(); 35 | } 36 | } 37 | 38 | render() { 39 | 40 | let viewBlock = ; 41 | 42 | switch (this.props.currView) { 43 | case 0: 44 | viewBlock = ; 45 | break; 46 | case 1: 47 | viewBlock = ; 48 | break; 49 | case 2: 50 | viewBlock = ; 51 | break; 52 | } 53 | 54 | let links = ['Out history', 'Our biography', 'Our skills'].map((item, index) => { 55 | let classes = `about-nav-item ${this.props.currView === index ? 'active' : ''}`; 56 | 57 | return ( 58 |
  • this.props.showView(index)}> 61 | {item} 62 |
  • 63 | ); 64 | }); 65 | 66 | return ( 67 |
    68 |
      69 | {links} 70 |
    71 | {viewBlock} 72 |
    73 | ); 74 | } 75 | } 76 | 77 | function mapStateToProps(state) { 78 | return { 79 | currView: state.about.currView, 80 | skillsShow: state.about.skillsShow 81 | } 82 | } 83 | 84 | function matchDispatchToProps(dispatch) { 85 | return bindActionCreators({ 86 | showView: actions.showView, 87 | showSkillsEnable: actions.showSkillsEnable 88 | }, dispatch) 89 | } 90 | 91 | export default connect(mapStateToProps, matchDispatchToProps)(AboutApp); -------------------------------------------------------------------------------- /js/src/containers/contactFormApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { bindActionCreators } from 'redux'; 3 | import { connect } from 'react-redux'; 4 | 5 | import * as actions from '../actions/contactFormActions.js'; 6 | 7 | class ContactFromApp extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | 11 | this.changeFieldHandler = this.changeFieldHandler.bind(this); 12 | this.handlerSubmit = this.handlerSubmit.bind(this); 13 | } 14 | 15 | changeFieldHandler(e) { 16 | this.props.changeFieldValue({text: e.target.value, type: e.target.name}); 17 | } 18 | 19 | handlerSubmit(e) { 20 | if (this.props.nameField.valid && this.props.nameField.text && 21 | this.props.emailField.valid && this.props.emailField.text && 22 | this.props.messageField.valid && this.props.messageField.text) { 23 | alert('Success, data sent to the server!'); 24 | } 25 | else { 26 | alert('Fail, data not valid or field is empty!'); 27 | e.preventDefault(); 28 | } 29 | } 30 | 31 | render() { 32 | return ( 33 |
    34 | Invalid characters at name field 35 | 36 | Invalid characters at email field 37 | 38 | Too short message (at least 20 characters) 39 |