├── .gitignore ├── README.md ├── virgo-codyframe ├── gulpfile.js ├── main │ ├── assets │ │ ├── css │ │ │ ├── _base.scss │ │ │ ├── _custom-style.scss │ │ │ ├── components │ │ │ │ ├── _1_3d-text-block.scss │ │ │ │ ├── _1_accordion.scss │ │ │ │ ├── _1_adv-gallery.scss │ │ │ │ ├── _1_anim-menu-btn.scss │ │ │ │ ├── _1_article-gallery-v3.scss │ │ │ │ ├── _1_author.scss │ │ │ │ ├── _1_background-decoration.scss │ │ │ │ ├── _1_banner.scss │ │ │ │ ├── _1_button-effects.scss │ │ │ │ ├── _1_details-list.scss │ │ │ │ ├── _1_devices.scss │ │ │ │ ├── _1_diagonal-section.scss │ │ │ │ ├── _1_feature-v10.scss │ │ │ │ ├── _1_feature-v9.scss │ │ │ │ ├── _1_google-maps.scss │ │ │ │ ├── _1_immersive-section-transition.scss │ │ │ │ ├── _1_link-effects.scss │ │ │ │ ├── _1_list-v2.scss │ │ │ │ ├── _1_list.scss │ │ │ │ ├── _1_main-footer.scss │ │ │ │ ├── _1_modal-window.scss │ │ │ │ ├── _1_newsletter.scss │ │ │ │ ├── _1_notice.scss │ │ │ │ ├── _1_pagination.scss │ │ │ │ ├── _1_radio-switch.scss │ │ │ │ ├── _1_radios-checkboxes.scss │ │ │ │ ├── _1_reading-progressbar.scss │ │ │ │ ├── _1_reveal-effects.scss │ │ │ │ ├── _1_search-input.scss │ │ │ │ ├── _1_skip-link.scss │ │ │ │ ├── _1_social-sharing.scss │ │ │ │ ├── _1_sticky-hero.scss │ │ │ │ ├── _1_testimonial.scss │ │ │ │ ├── _1_text-points.scss │ │ │ │ ├── _1_vertical-timeline.scss │ │ │ │ ├── _2_contact.scss │ │ │ │ ├── _2_device-group.scss │ │ │ │ ├── _2_flexi-header.scss │ │ │ │ ├── _2_image-interest-points.scss │ │ │ │ ├── _2_pricing-table.scss │ │ │ │ ├── _2_sticky-sharebar.scss │ │ │ │ └── _3_feature-v14.scss │ │ │ ├── custom-style │ │ │ │ ├── _buttons.scss │ │ │ │ ├── _colors.scss │ │ │ │ ├── _forms.scss │ │ │ │ ├── _icons.scss │ │ │ │ ├── _shared-styles.scss │ │ │ │ ├── _spacing.scss │ │ │ │ ├── _typography.scss │ │ │ │ └── _util.scss │ │ │ ├── style.css │ │ │ ├── style.min.css │ │ │ └── style.scss │ │ ├── img │ │ │ ├── article-example-img-1.svg │ │ │ ├── article-example-img-2.svg │ │ │ ├── article-gallery-v3-author-img-1.jpg │ │ │ ├── article-gallery-v3-img-1.jpg │ │ │ ├── article-gallery-v3-img-2.jpg │ │ │ ├── article-gallery-v3-img-3.jpg │ │ │ ├── article-img-1.jpg │ │ │ ├── favicon.svg │ │ │ ├── feature-v10-img-1.jpg │ │ │ ├── feature-v10-img-2.jpg │ │ │ ├── feature-v9-img-1.jpg │ │ │ ├── feature-v9-img-2.jpg │ │ │ ├── hero-diagonal-img-1.jpg │ │ │ ├── image-interest-points-img-1.jpg │ │ │ ├── image-interest-points-img-2.jpg │ │ │ ├── sticky-hero-img-1.jpg │ │ │ ├── testimonial-img-1.jpg │ │ │ └── vertical-timeline-img-1.jpg │ │ └── js │ │ │ ├── components │ │ │ ├── _1_accordion.js │ │ │ ├── _1_anim-menu-btn.js │ │ │ ├── _1_google-maps.js │ │ │ ├── _1_immersive-section-transition.js │ │ │ ├── _1_modal-window.js │ │ │ ├── _1_notice.js │ │ │ ├── _1_reading-progressbar.js │ │ │ ├── _1_reveal-effects.js │ │ │ ├── _1_skip-link.js │ │ │ ├── _1_social-sharing.js │ │ │ ├── _1_sticky-hero.js │ │ │ ├── _1_vertical-timeline.js │ │ │ ├── _2_flexi-header.js │ │ │ ├── _2_image-interest-points.js │ │ │ ├── _2_pricing-table.js │ │ │ └── _2_sticky-sharebar.js │ │ │ ├── scripts.js │ │ │ └── scripts.min.js │ ├── blog-article.html │ ├── blog.html │ ├── contact.html │ ├── index.html │ ├── pricing.html │ └── solutions.html └── package.json └── virgo-tailwind ├── assets └── img │ ├── article-example-img-1.svg │ ├── article-example-img-2.svg │ ├── article-gallery-v3-author-img-1.jpg │ ├── article-gallery-v3-img-1.jpg │ ├── article-gallery-v3-img-2.jpg │ ├── article-gallery-v3-img-3.jpg │ ├── article-img-1.jpg │ ├── favicon.svg │ ├── feature-v10-img-1.jpg │ ├── feature-v10-img-2.jpg │ ├── feature-v9-img-1.jpg │ ├── feature-v9-img-2.jpg │ ├── hero-diagonal-img-1.jpg │ ├── image-interest-points-img-1.jpg │ ├── image-interest-points-img-2.jpg │ ├── sticky-hero-img-1.jpg │ ├── testimonial-img-1.jpg │ └── vertical-timeline-img-1.jpg ├── dist └── output.css ├── src ├── blog-article.html ├── blog.html ├── contact.html ├── css │ └── input.css ├── index.html ├── js │ └── components.js ├── pricing.html └── solutions.html └── tailwind.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.DS_Store 3 | config.php 4 | package-lock.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Virgo Template by 🐞 CodyHouse 2 | Virgo is a free HTML, CSS, JS landing template built using the [CodyHouse Components](https://codyhouse.co/ds/components). It's compatible with [CodyFrame CSS](https://codyhouse.co/ds/docs/framework) and [Tailwind CSS](https://tailwindcss.com/). 3 | 4 | [View Demo](https://codyhouse.co/demo-templates/virgo/index.html) 5 | 6 | https://user-images.githubusercontent.com/5512545/142900965-b2566379-82ef-4d10-87af-d79711a39270.mp4 7 | 8 | ## Progressive enhancement 9 | The following script in the `` of the html files: 10 | 11 | ```html 12 | 13 | ``` 14 | 15 | is used in CSS to check if JavaScript is enabled and apply additional style accordingly. 16 | 17 | ## Gulp 18 | The CodyFrame version of the template includes a Gulp file with some basic configurations. 19 | 20 | To use this configuration file, once you have downloaded the template, run the following commands in your command line: 21 | 22 | ``` 23 | npm install 24 | npm run gulp watch 25 | ``` 26 | 27 | The first command will install the modules the framework requires for compiling SCSS into CSS; the second will launch your project on a development server. 28 | 29 | ## License 30 | Check [CodyHouse License page](https://codyhouse.co/license#templates). 31 | 32 | ## Credits 33 | 1. Images: [Unsplash](https://unsplash.com/) 34 | 2. Icons: [Nucleoapp](https://nucleoapp.com/) 35 | -------------------------------------------------------------------------------- /virgo-codyframe/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var sass = require('gulp-sass')(require('sass-embedded')); 3 | var sassGlob = require('gulp-sass-glob'); 4 | var browserSync = require('browser-sync').create(); 5 | var postcss = require('gulp-postcss'); 6 | var autoprefixer = require('autoprefixer'); 7 | var concat = require('gulp-concat'); 8 | var rename = require('gulp-rename'); 9 | var uglify = require('gulp-uglify'); 10 | var cleanCSS = require('gulp-clean-css'); 11 | var purgecss = require('gulp-purgecss'); 12 | 13 | // js file paths 14 | var utilJsPath = 'node_modules/codyhouse-framework/main/assets/js'; // util.js path - you may need to update this if including the framework as external node module 15 | var componentsJsPath = 'main/assets/js/components/*.js'; // component js files 16 | var scriptsJsPath = 'main/assets/js'; //folder for final scripts.js/scripts.min.js files 17 | 18 | // css file paths 19 | var cssFolder = 'main/assets/css'; // folder for final style.css/style-custom-prop-fallbac.css files 20 | var scssFilesPath = 'main/assets/css/**/*.scss'; // scss files to watch 21 | 22 | function reload(done) { 23 | browserSync.reload(); 24 | done(); 25 | } 26 | 27 | /* Gulp watch tasks */ 28 | // This task is used to convert the scss to css and compress it. 29 | gulp.task('sass', function() { 30 | return gulp.src(scssFilesPath) 31 | .pipe(sassGlob({sassModules: true})) 32 | .pipe(sass().on('error', sass.logError)) 33 | .pipe(postcss([autoprefixer()])) 34 | .pipe(gulp.dest(cssFolder)) 35 | .pipe(browserSync.reload({ 36 | stream: true 37 | })) 38 | .pipe(rename('style.min.css')) 39 | .pipe(cleanCSS()) 40 | .pipe(gulp.dest(cssFolder)) 41 | .pipe(browserSync.reload({ 42 | stream: true 43 | })); 44 | }); 45 | // This task is used to combine all js files in a single scripts.min.js. 46 | gulp.task('scripts', function() { 47 | return gulp.src([utilJsPath+'/util.js', componentsJsPath]) 48 | .pipe(concat('scripts.js')) 49 | .pipe(gulp.dest(scriptsJsPath)) 50 | .pipe(browserSync.reload({ 51 | stream: true 52 | })) 53 | .pipe(rename('scripts.min.js')) 54 | .pipe(uglify()) 55 | .pipe(gulp.dest(scriptsJsPath)) 56 | .pipe(browserSync.reload({ 57 | stream: true 58 | })); 59 | }); 60 | // This task is used to reload the project whan changes are made to a html/scss/js file. 61 | gulp.task('browserSync', gulp.series(function (done) { 62 | browserSync.init({ 63 | server: { 64 | baseDir: 'main' 65 | }, 66 | notify: false 67 | }) 68 | done(); 69 | })); 70 | 71 | gulp.task('watch', gulp.series(['browserSync', 'sass', 'scripts'], function () { 72 | gulp.watch('main/*.html', gulp.series(reload)); 73 | gulp.watch('main/assets/css/**/*.scss', gulp.series(['sass'])); 74 | gulp.watch(componentsJsPath, gulp.series(['scripts'])); 75 | })); 76 | 77 | 78 | /* Gulp dist task */ 79 | // create a distribution folder for production 80 | var distFolder = 'dist/'; 81 | var assetsFolder = 'dist/assets/'; 82 | 83 | gulp.task('dist', async function(){ 84 | // remove unused classes from the style.css file with PurgeCSS and copy it to the dist folder 85 | await purgeCSS(); 86 | // minify the scripts.js file and copy it to the dist folder 87 | await minifyJs(); 88 | // copy any additional js files to the dist folder 89 | await moveJS(); 90 | // copy all the assets inside main/assets/img folder to the dist folder 91 | await moveAssets(); 92 | // copy all html files inside main folder to the dist folder 93 | await moveContent(); 94 | console.log('Distribution task completed!') 95 | }); 96 | 97 | function purgeCSS() { 98 | return new Promise(function(resolve, reject) { 99 | var stream = gulp.src(cssFolder+'/style.css') 100 | .pipe(purgecss({ 101 | content: ['main/*.html', scriptsJsPath+'/scripts.js'], 102 | safelist: { 103 | standard: ['.is-hidden', '.is-visible'], 104 | deep: [/class$/], 105 | greedy: [] 106 | }, 107 | defaultExtractor: content => content.match(/[\w-/:%@]+(? * { 57 | transform-origin: 8px 8px; 58 | } 59 | } 60 | } 61 | 62 | .accordion__icon-arrow, 63 | .accordion__icon-arrow-v2 { 64 | .icon__group { 65 | > * { 66 | stroke-dasharray: 17; 67 | transform: translateY(3px); 68 | } 69 | 70 | > *:first-child { 71 | stroke-dashoffset: 8.5; 72 | } 73 | 74 | > *:last-child { 75 | stroke-dashoffset: 8.5; 76 | } 77 | } 78 | } 79 | 80 | .accordion__icon-plus { 81 | .icon__group { 82 | transform: rotate(-90deg); 83 | 84 | > *:first-child { 85 | transform: rotate(-90deg); 86 | } 87 | } 88 | } 89 | 90 | .accordion__item--is-open > .accordion__header { 91 | > .accordion__icon-arrow .icon__group { // animated arrow icon 92 | > *:first-child { 93 | transform: translateY(-3px) rotate(-90deg); 94 | } 95 | 96 | > *:last-child { 97 | transform: translateY(-3px) rotate(90deg); 98 | } 99 | } 100 | 101 | > .accordion__icon-arrow-v2 .icon__group { // animated arrow icon v2 102 | transform: rotate(-90deg); 103 | 104 | > *:first-child, *:last-child { 105 | stroke-dashoffset: 0; 106 | transform: translateY(0px); 107 | } 108 | } 109 | 110 | > .accordion__icon-plus .icon__group { // animated plus icon 111 | transform: rotate(0); 112 | 113 | > *:first-child { 114 | transform: rotate(0); 115 | } 116 | } 117 | } 118 | 119 | .js { 120 | .accordion__panel { 121 | display: none; 122 | will-change: height; 123 | transform: translateZ(0px); 124 | } 125 | 126 | .accordion__item--is-open > .accordion__panel { 127 | display: block; 128 | } 129 | } 130 | 131 | // animations 132 | .accordion[data-animation="on"] { 133 | .accordion__item--is-open .accordion__panel > * { 134 | animation: accordion-entry-animation .4s var(--ease-out); 135 | } 136 | 137 | .accordion__icon-arrow, 138 | .accordion__icon-arrow-v2, 139 | .accordion__icon-plus { 140 | .icon__group { 141 | transition: transform .3s var(--ease-out); 142 | 143 | > * { 144 | transition: transform .3s, stroke-dashoffset .3s; 145 | transition-timing-function: var(--ease-out); 146 | } 147 | } 148 | } 149 | } 150 | 151 | @keyframes accordion-entry-animation { 152 | from { 153 | opacity: 0; 154 | transform: translateY(-10px); 155 | } 156 | 157 | to { 158 | opacity: 1; 159 | transform: translateY(0px); 160 | } 161 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_adv-gallery.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_adv-gallery 6 | Title: Advanced Gallery 7 | Descr: Advanced image gallery template 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .adv-gallery { 13 | position: relative; 14 | z-index: 1; 15 | } 16 | 17 | .adv-gallery__img { 18 | width: 100%; 19 | display: block; 20 | object-fit: cover; 21 | } 22 | 23 | // CSS Grid fallback 24 | .adv-gallery__grid { 25 | > * { 26 | margin-bottom: var(--space-md); 27 | } 28 | 29 | @include breakpoint(md) { 30 | > :nth-child(1), > :nth-child(2), > :nth-child(3) { 31 | width: 32%; 32 | float: left; 33 | } 34 | 35 | > :nth-child(1), > :nth-child(2) { 36 | margin-right: 2%; 37 | } 38 | 39 | > :nth-child(4) { 40 | clear: both; 41 | } 42 | } 43 | } 44 | 45 | // if CSS Grid = supported 46 | @supports (grid-area: auto) { 47 | .adv-gallery__grid { 48 | display: grid; 49 | grid-gap: var(--space-md); 50 | 51 | > * { // fallback reset 52 | margin: 0 !important; 53 | width: auto !important; 54 | float: none !important; 55 | } 56 | } 57 | 58 | @include breakpoint(md) { 59 | .adv-gallery__grid { 60 | grid-template-columns: repeat(12, 1fr); 61 | 62 | > :nth-child(1) { 63 | grid-column: span 5; 64 | } 65 | 66 | > :nth-child(2) { 67 | grid-column: span 7; 68 | } 69 | 70 | > :nth-child(3) { 71 | grid-column: span 9; 72 | } 73 | 74 | > :nth-child(4) { 75 | grid-column: span 3; 76 | } 77 | } 78 | } 79 | 80 | @include breakpoint(lg) { 81 | .adv-gallery__grid { 82 | grid-gap: var(--space-sm); 83 | grid-template-rows: repeat(12, 50px); 84 | 85 | > :nth-child(1) { 86 | grid-column: 1 / 4; 87 | grid-row: 1 / 7; 88 | } 89 | 90 | > :nth-child(2) { 91 | grid-column: 1 / 4; 92 | grid-row: 7 / -1; 93 | } 94 | 95 | > :nth-child(3) { 96 | grid-column: 4 / 11; 97 | grid-row: 1 / -1; 98 | } 99 | 100 | > :nth-child(4) { 101 | grid-column: 11 / 13; 102 | grid-row: 1 / -1; 103 | } 104 | } 105 | 106 | .adv-gallery__img { 107 | height: 100%; 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_anim-menu-btn.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_anim-menu-btn 6 | Title: Animated Menu Button 7 | Descr: A menu button w/ a morphing icon 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | :root { 13 | --anim-menu-btn-size: 48px; 14 | --anim-menu-btn-transition-duration: .2s; 15 | 16 | // 🍔 icon 17 | --anim-menu-btn-icon-size: 32px; 18 | --anim-menu-btn-icon-stroke: 2px; 19 | } 20 | 21 | .anim-menu-btn { 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | width: var(--anim-menu-btn-size); 26 | height: var(--anim-menu-btn-size); 27 | } 28 | 29 | // icons 30 | .anim-menu-btn__icon { 31 | position: relative; 32 | display: block; 33 | font-size: var(--anim-menu-btn-icon-size); 34 | width: 1em; 35 | height: var(--anim-menu-btn-icon-stroke); 36 | color: inherit; 37 | background-image: linear-gradient(currentColor, currentColor); 38 | background-repeat: no-repeat; 39 | transform: scale(1); 40 | 41 | &::before, &::after { 42 | content: ''; 43 | position: absolute; 44 | top: 0; 45 | left: 0; 46 | height: 100%; 47 | width: 100%; 48 | background-image: inherit; 49 | border-radius: inherit; 50 | } 51 | } 52 | 53 | // menu to 'X' close 54 | .anim-menu-btn__icon--close { 55 | background-size: 100% 100%; 56 | will-change: transform, background-size; 57 | transition-property: transform, background-size; 58 | transition-duration: var(--anim-menu-btn-transition-duration, 0.2s); 59 | 60 | .anim-menu-btn:active & { 61 | transform: scale(0.9); 62 | } 63 | 64 | &::before, &::after { 65 | will-change: inherit; 66 | transition: inherit; 67 | } 68 | 69 | &::before { // line top 70 | transform: translateY(-0.25em) rotate(0); 71 | } 72 | 73 | &::after { // line bottom 74 | transform: translateY(0.25em) rotate(0); 75 | } 76 | } 77 | 78 | .anim-menu-btn--state-b { 79 | .anim-menu-btn__icon--close { 80 | background-size: 0% 100%; 81 | 82 | &::before { 83 | transform: translateY(0) rotate(45deg); 84 | } 85 | 86 | &::after { 87 | transform: translateY(0) rotate(-45deg); 88 | } 89 | } 90 | } 91 | 92 | // menu to arrow 93 | .anim-menu-btn__icon--arrow-left, 94 | .anim-menu-btn__icon--arrow-right, 95 | .anim-menu-btn__icon--arrow-up, 96 | .anim-menu-btn__icon--arrow-down { 97 | border-radius: 50em; 98 | will-change: transform; 99 | transition-property: transform; 100 | transition-duration: var(--anim-menu-btn-transition-duration, 0.2s); 101 | 102 | .anim-menu-btn:active & { 103 | transform: scale(0.9); 104 | } 105 | 106 | &::before, &::after { 107 | transform-origin: calc(var(--anim-menu-btn-icon-stroke)/2) 50%; 108 | will-change: transform, width; 109 | transition-property: transform, width; 110 | transition-duration: var(--anim-menu-btn-transition-duration, 0.2s); 111 | } 112 | 113 | &::before { // line top 114 | transform: translateY(-0.25em) rotate(0); 115 | } 116 | 117 | &::after { // line bottom 118 | transform: translateY(0.25em) rotate(0); 119 | } 120 | } 121 | 122 | .anim-menu-btn__icon--arrow-right { 123 | transform: rotate(180deg); 124 | 125 | .anim-menu-btn:active & { 126 | transform: rotate(180deg) scale(0.9); 127 | } 128 | } 129 | 130 | .anim-menu-btn--state-b { 131 | .anim-menu-btn__icon--arrow-left, 132 | .anim-menu-btn__icon--arrow-right, 133 | .anim-menu-btn__icon--arrow-up, 134 | .anim-menu-btn__icon--arrow-down { 135 | &::before, &::after { 136 | width: 50%; 137 | } 138 | 139 | &::before { 140 | transform: translateY(0) rotate(-45deg); 141 | } 142 | 143 | &::after { 144 | transform: translateY(0) rotate(45deg); 145 | } 146 | } 147 | 148 | &:active .anim-menu-btn__icon--arrow-up { 149 | transform: rotate(90deg) scale(0.9); 150 | } 151 | 152 | .anim-menu-btn__icon--arrow-up { 153 | transform: rotate(90deg); 154 | } 155 | 156 | &:active .anim-menu-btn__icon--arrow-down { 157 | transform: rotate(-90deg) scale(0.9); 158 | } 159 | 160 | .anim-menu-btn__icon--arrow-down { 161 | transform: rotate(-90deg); 162 | } 163 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_article-gallery-v3.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_article-gallery-v3 6 | Title: Article Gallery v3 7 | Descr: A gallery of blog articles 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .articles-v3 {} 13 | 14 | .articles-v3__img { 15 | display: block; 16 | transition: opacity .3s; 17 | border-radius: var(--radius-md); 18 | overflow: hidden; 19 | 20 | img { 21 | display: block; 22 | width: 100%; 23 | } 24 | 25 | &:hover { 26 | opacity: 0.85; 27 | } 28 | } 29 | 30 | .articles-v3__headline { 31 | font-size: var(--text-xl); 32 | 33 | a { 34 | color: var(--color-contrast-higher); 35 | text-decoration: none; 36 | 37 | &:hover { 38 | text-decoration: underline; 39 | } 40 | } 41 | } 42 | 43 | .articles-v3__author { 44 | display: grid; 45 | grid-template-columns: 3em 1fr; 46 | grid-gap: var(--space-xs); 47 | align-items: center; 48 | margin-top: var(--space-md); 49 | } 50 | 51 | .articles-v3__author-img { 52 | display: block; 53 | width: 3em; 54 | height: 3em; 55 | border-radius: 50%; 56 | overflow: hidden; 57 | transition: transform .3s var(--ease-out-back); 58 | 59 | img { 60 | display: block; 61 | width: inherit; 62 | height: inherit; 63 | } 64 | 65 | &:hover { 66 | transform: scale(1.1); 67 | } 68 | } 69 | 70 | .articles-v3__author-name { 71 | font-weight: bold; 72 | color: var(--color-contrast-higher); 73 | text-decoration: none; 74 | 75 | &:hover { 76 | text-decoration: underline; 77 | } 78 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_author.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_author 6 | Title: Author 7 | Descr: Author introduction card 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | :root { 13 | --author-img-size: 4em; 14 | } 15 | 16 | .author { 17 | display: grid; 18 | grid-template-columns: var(--author-img-size) 1fr; 19 | grid-gap: var(--space-sm); 20 | } 21 | 22 | .author__img-wrapper { // img link 23 | display: inline-block; 24 | border-radius: 50%; 25 | width: var(--author-img-size); 26 | height: var(--author-img-size); 27 | overflow: hidden; 28 | transition: transform .3s var(--ease-out-back); 29 | 30 | &:hover { 31 | transform: scale(1.1); 32 | } 33 | 34 | img { 35 | display: block; 36 | width: inherit; 37 | height: inherit; 38 | object-fit: cover; 39 | } 40 | } 41 | 42 | .author__content { 43 | a { 44 | color: inherit; 45 | 46 | &:hover { 47 | color: var(--color-primary); 48 | } 49 | } 50 | } 51 | 52 | // --meta -> show date + read time 53 | .author--meta { 54 | --author-img-size: 3em; 55 | align-items: center; 56 | grid-gap: var(--space-xs); 57 | } 58 | 59 | // --minimal -> show only author name 60 | .author--minimal { 61 | --author-img-size: 2.4em; 62 | align-items: center; 63 | grid-gap: var(--space-xxs); 64 | } 65 | 66 | // --featured -> expand author info 67 | .author--featured { 68 | --author-img-size: 6em; 69 | grid-template-columns: 1fr; 70 | justify-content: center; 71 | text-align: center; 72 | 73 | .author__img-wrapper { 74 | margin-left: auto; 75 | margin-right: auto; 76 | } 77 | } 78 | 79 | .author__social { // social button 80 | --size: 40px; 81 | width: var(--size); 82 | height: var(--size); 83 | display: flex; 84 | 85 | background-color: alpha(var(--color-contrast-higher), 0.1); 86 | border-radius: 50%; 87 | transition: .2s; 88 | 89 | .icon { 90 | --size: 16px; 91 | display: block; 92 | margin: auto; 93 | color: var(--color-contrast-higher); 94 | transition: color .2s; 95 | } 96 | 97 | &:hover { 98 | background-color: alpha(var(--color-contrast-higher), 0.075); 99 | 100 | .icon { 101 | color: var(--color-primary); 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_background-decoration.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_background-decoration 6 | Title: Background Decoration 7 | Descr: A collection of background effects 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .bg-decoration { 13 | position: absolute; 14 | top: 0; 15 | left: 0; 16 | pointer-events: none; 17 | width: 100%; 18 | height: 100%; 19 | overflow: hidden; 20 | } 21 | 22 | .bg-decoration__svg { 23 | position: absolute; 24 | top: 0; 25 | left: 50%; 26 | transform: translateX(-50%); 27 | width: 134%; 28 | min-width: 1280px; 29 | max-width: 1920px; 30 | height: auto; 31 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_banner.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_banner 6 | Title: Banner 7 | Descr: A CTA banner containing text + media 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .banner { 13 | display: block; 14 | text-decoration: none; 15 | color: inherit; 16 | overflow: hidden; 17 | 18 | background-color: var(--color-bg-light); 19 | box-shadow: var(--inner-glow), var(--shadow-sm); 20 | border-radius: var(--radius-md); 21 | 22 | transition: .3s; 23 | 24 | &:hover { 25 | background-color: var(--color-bg-lighter); 26 | box-shadow: var(--inner-glow), var(--shadow-md); 27 | 28 | .banner__link { 29 | transform: scale(1.3); 30 | 31 | i { 32 | transform: scale(0.7); // reverse parent transformation 33 | } 34 | 35 | &::after { 36 | height: 100%; 37 | } 38 | } 39 | 40 | .banner__figure { 41 | transform: scale(1.05); 42 | } 43 | } 44 | } 45 | 46 | .banner__link { 47 | position: relative; 48 | text-decoration: none; 49 | color: var(--color-primary-dark); 50 | display: inline-block; 51 | transition: .3s var(--ease-out); 52 | transform-origin: left bottom; 53 | 54 | i { // label 55 | position: relative; 56 | z-index: 2; 57 | display: inline-block; 58 | transition: .3s var(--ease-out); 59 | } 60 | 61 | &::after { // animated border 62 | content: ''; 63 | background-color: currentColor; 64 | height: 2px; 65 | width: 100%; 66 | position: absolute; 67 | z-index: 1; 68 | bottom: 0; 69 | left: 0; 70 | transition: .3s var(--ease-out); 71 | opacity: 0.15; 72 | } 73 | } 74 | 75 | .banner__figure { 76 | height: 0; 77 | padding-bottom: 50%; 78 | transition: .3s var(--ease-out); 79 | background-position: center center; 80 | background-repeat: no-repeat; 81 | background-size: cover; 82 | } 83 | 84 | @include breakpoint(md) { 85 | .banner__figure { 86 | height: 100%; 87 | padding-bottom: 0; 88 | clip-path: polygon(100px 0%, 100% 0%, 100% 100%, 50px 100%); 89 | } 90 | 91 | // invert variation 92 | .banner--invert { 93 | .banner__figure { 94 | clip-path: polygon(0% 0%, calc(100% - 100px) 0%, calc(100% - 50px) 100%, 0% 100%); 95 | } 96 | 97 | .banner__link { 98 | transform-origin: right bottom; 99 | } 100 | } 101 | 102 | .banner:hover .banner__figure { // clip animation - visible on big screens 103 | clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); 104 | } 105 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_button-effects.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_button-effects 6 | Title: Button Effects 7 | Descr: A collection of button effects 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | // v1 13 | .btn-fx-1 { 14 | --border-radius: 0.25em; 15 | --transition-duration: .3s; 16 | position: relative; 17 | display: inline-block; 18 | border-radius: var(--border-radius); 19 | 20 | line-height: 1; 21 | text-decoration: none; 22 | color: var(--color-primary); // text color 23 | transition: var(--transition-duration); 24 | @include fontSmooth; 25 | 26 | cursor: pointer; 27 | 28 | span, .btn-fx-1__icon-wrapper { // place label and icon above animated background 29 | position: relative; 30 | z-index: 2; 31 | } 32 | 33 | .icon { 34 | display: block; 35 | will-change: transform; 36 | transition: var(--transition-duration); 37 | } 38 | 39 | .icon:first-child { 40 | color: var(--color-primary); // icon color 41 | } 42 | 43 | .icon:last-child { 44 | position: absolute; 45 | top: 0; 46 | left: 0; 47 | opacity: 0; 48 | color: var(--color-white); // icon color on hover 49 | transform: translateY(100%); 50 | } 51 | 52 | &:hover { 53 | color: var(--color-white); // text color on hover 54 | 55 | .icon:first-child { 56 | opacity: 0; 57 | transform: translateY(-100%); 58 | } 59 | 60 | .icon:last-child { 61 | opacity: 1; 62 | transform: translateY(0); 63 | } 64 | 65 | & .btn-fx-1__inner::after { 66 | transform: skewY(0deg) scaleY(2); 67 | } 68 | } 69 | 70 | &:focus { 71 | outline: none; 72 | box-shadow: 0 0 0 1px var(--color-bg), 0 0 0 3px var(--color-primary); 73 | } 74 | } 75 | 76 | .btn-fx-1__inner { // trick - used to fix issue on Safari 77 | position: relative; 78 | display: inline-flex; 79 | justify-content: center; 80 | align-items: center; // vertically align label + icon 81 | 82 | background-color: alpha(var(--color-primary), 0.15); // starting bg color 83 | overflow: hidden; 84 | clip-path: inset(0% 0% 0% 0% round var(--border-radius)); 85 | 86 | &::after { // animated background 87 | content: ''; 88 | position: absolute; 89 | z-index: 1; 90 | top: 50%; 91 | left: -5%; 92 | width: 110%; 93 | height: 100%; 94 | background-color: var(--color-primary); // ending bg color 95 | transform-origin: center bottom; 96 | transform: skewY(10deg) scaleY(0); 97 | transition: transform var(--transition-duration); 98 | } 99 | } 100 | 101 | // v2 102 | .btn-fx-2 { 103 | position: relative; 104 | 105 | line-height: 1; 106 | letter-spacing: 0.1em; 107 | text-transform: uppercase; 108 | text-decoration: none; 109 | 110 | span { 111 | position: relative; 112 | display: inline-flex; 113 | clip-path: inset(0%); 114 | } 115 | 116 | em { 117 | display: inline-flex; 118 | 119 | * { 120 | color: var(--color-primary); // text color 121 | padding: 0.25em 0; 122 | will-change: transform; 123 | transition: transform .3s; 124 | } 125 | 126 | &:last-child { 127 | position: absolute; 128 | top: 0; 129 | left: 0; 130 | 131 | * { 132 | transform: translateY(100%); 133 | } 134 | } 135 | } 136 | 137 | &::before, &::after { // animated line 138 | content: ''; 139 | position: absolute; 140 | bottom: 0; 141 | height: 2px; 142 | left: 0; 143 | width: 100%; 144 | } 145 | 146 | &::before { // bg 147 | background-color: alpha(var(--color-primary), 0.2); 148 | } 149 | 150 | &::after { // filling effect 151 | background-color: var(--color-primary); 152 | transform: scaleX(0); 153 | transition: transform .3s; 154 | transform-origin: right center; 155 | } 156 | 157 | &:hover { 158 | // :nth-child(x), where x = number of letters 159 | em { 160 | *:nth-child(2) { 161 | transition-delay: .05s; 162 | } 163 | 164 | *:nth-child(3) { 165 | transition-delay: .1s; 166 | } 167 | 168 | *:nth-child(4) { 169 | transition-delay: .15s; 170 | } 171 | 172 | *:nth-child(5) { 173 | transition-delay: .2s; 174 | } 175 | 176 | *:nth-child(6) { 177 | transition-delay: .25s; 178 | } 179 | 180 | *:nth-child(7) { 181 | transition-delay: .3s; 182 | } 183 | 184 | *:nth-child(8) { 185 | transition-delay: .35s; 186 | } 187 | 188 | *:nth-child(9) { 189 | transition-delay: .4s; 190 | } 191 | 192 | *:nth-child(10) { 193 | transition-delay: .45s; 194 | } 195 | } 196 | 197 | em:first-child { 198 | * { 199 | transform: translateY(-100%); 200 | } 201 | } 202 | 203 | em:last-child { 204 | * { 205 | transform: translateY(0); 206 | } 207 | } 208 | 209 | &::after { 210 | transform: scaleX(1); 211 | transform-origin: left center; 212 | } 213 | } 214 | } 215 | 216 | // v3 217 | .btn-fx-3 { 218 | --transition-duration: 0.3s; 219 | position: relative; 220 | display: inline-block; 221 | 222 | color: var(--color-bg); 223 | line-height: 1; 224 | text-decoration: none; 225 | @include fontSmooth; 226 | 227 | cursor: pointer; 228 | 229 | will-change: transform; 230 | transition: transform var(--transition-duration); 231 | 232 | span { // text label 233 | will-change: transform; 234 | transition: opacity var(--transition-duration), transform var(--transition-duration) var(--ease-out); 235 | } 236 | 237 | &::before { // animated background 238 | content: ''; 239 | position: absolute; 240 | left: 0; 241 | top: 0; 242 | width: 100%; 243 | height: 100%; 244 | background-color: var(--color-contrast-higher); 245 | border-radius: inherit; 246 | will-change: transform; 247 | transition: transform var(--transition-duration) var(--ease-out-back), box-shadow var(--transition-duration); 248 | } 249 | 250 | &:active { 251 | transform: scale(0.9); 252 | } 253 | 254 | &:hover { 255 | span { // text label 256 | opacity: 0; 257 | transform: scale(0.5); 258 | } 259 | 260 | &::before { // bg 261 | transform: scale(1.1); 262 | } 263 | 264 | .btn-fx-3__icon-wrapper { // icon 265 | transform: translateY(0); 266 | } 267 | } 268 | 269 | &:focus { 270 | outline: none; 271 | 272 | &::before { 273 | box-shadow: var(--shadow-sm), 0 0 0 3px alpha(var(--color-contrast-higher), 0.15); 274 | } 275 | } 276 | } 277 | 278 | .btn-fx-3__inner { 279 | position: relative; 280 | z-index: 2; 281 | display: inline-flex; 282 | justify-content: center; 283 | align-items: center; 284 | overflow: hidden; 285 | clip-path: inset(0%); 286 | } 287 | 288 | .btn-fx-3__icon-wrapper { 289 | position: absolute; 290 | z-index: 2; 291 | top: 0; 292 | left: 0; 293 | width: 100%; 294 | height: 100%; 295 | display: flex; 296 | will-change: transform; 297 | transform: translateY(100%); 298 | transition: transform var(--transition-duration) var(--ease-out); 299 | 300 | .icon { 301 | margin: auto; 302 | } 303 | } 304 | 305 | // v4 306 | .btn-fx-4 { 307 | --transition-duration: .3s; 308 | position: relative; 309 | display: inline-flex; 310 | justify-content: center; 311 | align-items: center; 312 | 313 | background-color: var(--color-contrast-higher); 314 | box-shadow: var(--shadow-sm); 315 | overflow: hidden; 316 | 317 | line-height: 1; 318 | text-decoration: none; 319 | color: var(--color-bg); 320 | @include fontSmooth; 321 | 322 | transition: var(--transition-duration); 323 | 324 | span { 325 | position: relative; 326 | z-index: 2; 327 | } 328 | 329 | &::before { // shiny effect 330 | content: ''; 331 | position: absolute; 332 | z-index: 1; 333 | top: 0; 334 | left: 0; 335 | height: 100%; 336 | width: 100%; 337 | background-color: alpha(var(--color-bg), 0.25); 338 | will-change: transform; 339 | transform: skewX(-15deg) translate(calc(-100% - 0.5em)); 340 | pointer-events: none; 341 | } 342 | 343 | &:hover { 344 | &::before { 345 | transform: skewX(-15deg) translate(calc(100% + 0.5em)); 346 | transition: transform var(--transition-duration); 347 | } 348 | } 349 | 350 | &:focus { 351 | outline: none; 352 | box-shadow: var(--shadow-sm), 0 0 0 3px alpha(var(--color-contrast-higher), 0.15); 353 | } 354 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_details-list.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_details-list 6 | Title: Details List 7 | Descr: Pairs of related information displayed in a list 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | :root { 13 | --details-list-border-width: 1px; 14 | --details-list-border-opacity: 0.15; 15 | } 16 | 17 | .details-list {} 18 | 19 | .details-list--rows { 20 | .details-list__item { 21 | border-bottom: var(--details-list-border-width) solid alpha(var(--color-contrast-higher), var(--details-list-border-opacity)); 22 | 23 | &:last-child { 24 | border-bottom: none; 25 | } 26 | } 27 | } 28 | 29 | .details-list--cols { 30 | .details-list__item { 31 | border-right: var(--details-list-border-width) solid alpha(var(--color-contrast-higher), var(--details-list-border-opacity)); 32 | 33 | &:last-child { 34 | border-right: none; 35 | } 36 | } 37 | } 38 | 39 | @each $breakpoint, $value in $breakpoints { 40 | @include breakpoint(#{$breakpoint}) { 41 | .details-list--rows\@#{$breakpoint} { 42 | .details-list__item { 43 | border-right: 0; 44 | border-bottom: var(--details-list-border-width) solid alpha(var(--color-contrast-higher), var(--details-list-border-opacity)); 45 | 46 | &:last-child { 47 | border-bottom: none; 48 | } 49 | } 50 | } 51 | 52 | .details-list--cols\@#{$breakpoint} { 53 | .details-list__item { 54 | border-bottom: 0; 55 | border-right: var(--details-list-border-width) solid alpha(var(--color-contrast-higher), var(--details-list-border-opacity)); 56 | 57 | &:last-child { 58 | border-right: none; 59 | } 60 | } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_diagonal-section.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_diagonal-section 6 | Title: Diagonal Section 7 | Descr: Section with diagonal edges 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | :root { 13 | --diagonal-section-offset: 50px; 14 | } 15 | 16 | .diagonal-section, 17 | .diagonal-section-top, 18 | .diagonal-section-bottom { 19 | position: relative; 20 | z-index: 1; 21 | background-size: cover; 22 | background-repeat: no-repeat; 23 | background-position: center; 24 | } 25 | 26 | @supports (clip-path: inset(50%)) { 27 | .diagonal-section, .diagonal-section-top.diagonal-section-bottom { 28 | padding-top: calc(var(--diagonal-section-offset)/2); 29 | padding-bottom: calc(var(--diagonal-section-offset)/2); 30 | clip-path: polygon(0% 0%, 100% var(--diagonal-section-offset), 100% 100%, 0% calc(100% - var(--diagonal-section-offset))); 31 | } 32 | 33 | .diagonal-section--flip-x { 34 | clip-path: polygon(0% var(--diagonal-section-offset), 100% 0%, 100% calc(100% - var(--diagonal-section-offset)), 0% 100%); 35 | } 36 | 37 | .diagonal-section-top { 38 | padding-top: calc(var(--diagonal-section-offset)/2); 39 | clip-path: polygon(0% 0%, 100% var(--diagonal-section-offset), 100% 100%, 0% 100%); 40 | 41 | } 42 | 43 | .diagonal-section-top--flip-x { 44 | clip-path: polygon(0% var(--diagonal-section-offset), 100% 0%, 100% 100%, 0% 100%); 45 | 46 | &.diagonal-section-bottom { 47 | clip-path: polygon(0% var(--diagonal-section-offset), 100% 0%, 100% 100%, 0% calc(100% - var(--diagonal-section-offset))); 48 | } 49 | } 50 | 51 | .diagonal-section-bottom { 52 | padding-bottom: calc(var(--diagonal-section-offset)/2); 53 | clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% calc(100% - var(--diagonal-section-offset))); 54 | } 55 | 56 | .diagonal-section-bottom--flip-x { 57 | clip-path: polygon(0% 0%, 100% 0%, 100% calc(100% - var(--diagonal-section-offset)), 0% 100%); 58 | 59 | &.diagonal-section-top { 60 | clip-path: polygon(0% 0%, 100% var(--diagonal-section-offset), 100% calc(100% - var(--diagonal-section-offset)), 0% 100%); 61 | } 62 | } 63 | 64 | .diagonal-section-top--flip-x.diagonal-section-bottom--flip-x { 65 | clip-path: polygon(0% var(--diagonal-section-offset), 100% 0%, 100% calc(100% - var(--diagonal-section-offset)), 0% 100%); 66 | } 67 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_feature-v10.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_feature-v10 6 | Title: Feature v10 7 | Descr: A feature section containing two adjacent content blocks 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .feature-v10 { 13 | position: relative; 14 | z-index: 1; 15 | } 16 | 17 | .feature-v10__link { 18 | position: relative; 19 | text-decoration: none; 20 | color: inherit; 21 | display: inline-block; 22 | transition: .3s var(--ease-out); 23 | transform-origin: left bottom; 24 | 25 | i { // label 26 | position: relative; 27 | z-index: 2; 28 | display: inline-block; 29 | transition: .3s var(--ease-out); 30 | } 31 | 32 | &::after { // animated border 33 | content: ''; 34 | background-color: currentColor; 35 | height: 2px; 36 | width: 100%; 37 | position: absolute; 38 | z-index: 1; 39 | bottom: 0; 40 | left: 0; 41 | transition: .3s var(--ease-out); 42 | opacity: 0.15; 43 | } 44 | 45 | &:hover { 46 | transform: scale(1.3); 47 | 48 | i { 49 | transform: scale(0.7); // reverse parent transformation 50 | } 51 | 52 | &::after { 53 | height: 100%; 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_feature-v9.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_feature-v9 6 | Title: Feature v9 7 | Descr: A feature section with 2 blocks 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .feature-v9 { 13 | &:hover .feature-v9__block:not(:hover) .feature-v9__content { 14 | opacity: 0.5; 15 | } 16 | 17 | &:hover .feature-v9__block:not(:hover)::after { 18 | background-color: alpha(var(--color-black), 0.8); 19 | backdrop-filter: grayscale(100%); 20 | } 21 | } 22 | 23 | .feature-v9__block { 24 | position: relative; 25 | display: flex; 26 | background-size: cover; 27 | background-repeat: no-repeat; 28 | background-position: center; 29 | padding: var(--space-xl) var(--space-md); 30 | min-height: 350px; 31 | 32 | &::before, &::after { 33 | content: ''; 34 | position: absolute; 35 | z-index: 1; 36 | bottom: 0; 37 | left: 0; 38 | width: 100%; 39 | transition: .2s; 40 | } 41 | 42 | &::before { // gradient under the content 43 | height: 70%; 44 | background: linear-gradient(alpha(var(--color-black), 0), alpha(var(--color-black), 0.8)); 45 | mix-blend-mode: multiply; 46 | } 47 | 48 | &::after { // overlay layer 49 | height: 100%; 50 | background-color: alpha(var(--color-black), 0); 51 | } 52 | 53 | &:hover .feature-v9__content { 54 | transform: translateY(-10px); 55 | } 56 | 57 | @include breakpoint(sm) { 58 | min-height: 450px; 59 | } 60 | 61 | @include breakpoint(md) { 62 | min-height: 600px; 63 | } 64 | 65 | @include breakpoint(lg) { 66 | min-height: 700px; 67 | } 68 | } 69 | 70 | .feature-v9__content { 71 | position: relative; 72 | z-index: 2; 73 | color: var(--color-white); 74 | @include fontSmooth; 75 | margin: auto auto 0; 76 | transition: .2s; 77 | } 78 | 79 | .feature-v9__link { 80 | color: var(--color-black); 81 | text-decoration: none; 82 | display: inline-block; 83 | padding: var(--space-xs) var(--space-md); 84 | background-color: alpha(var(--color-white), 0.8); 85 | border-radius: var(--radius-md); 86 | backdrop-filter: blur(5px); 87 | transition: background-color .2s; 88 | 89 | &:hover { 90 | background-color: alpha(var(--color-white), 1); 91 | } 92 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_google-maps.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_google-maps 6 | Title: Google Maps 7 | Descr: Google Maps component 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .google-maps { 13 | width: 100%; 14 | height: 0; 15 | padding-bottom: 56.25%; // set 16:9 aspect ratio 16 | } 17 | 18 | .google-maps--ratio-4\:1 { 19 | padding-bottom: 25%; 20 | } 21 | 22 | .google-maps--ratio-3\:1 { 23 | padding-bottom: 33%; 24 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_immersive-section-transition.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_immersive-section-transition 6 | Title: Immersive Section Transition 7 | Descr: A media element that animates to a full-screen block, before transitioning to the next section of content 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .js { 13 | .immerse-section-tr { 14 | position: relative; 15 | --immerse-section-tr-opacity: 0; // overlay layer opacity - modified using JS 16 | } 17 | 18 | .immerse-section-tr__media { 19 | position: sticky; 20 | top: 0; 21 | z-index: 1; 22 | overflow: hidden; 23 | pointer-events: none; 24 | } 25 | 26 | .immerse-section-tr--disabled .immerse-section-tr__media { // this class is added in JS if effect is deactivated 27 | position: relative; 28 | } 29 | 30 | .immerse-section-tr__figure { // asset to scale up 31 | will-change: transform; 32 | pointer-events: auto; 33 | // make asset responsive 34 | position: relative; 35 | height: 0; 36 | 37 | 38 | > * { 39 | position: absolute; 40 | top: 0; 41 | left: 0; 42 | width: 100%; 43 | height: 100%; 44 | object-fit: cover; 45 | } 46 | } 47 | 48 | .immerse-section-tr__figure--16-9 { // 16:9 aspect ratio 49 | padding-bottom: 56.25%; 50 | } 51 | 52 | .immerse-section-tr__figure--3-4 { // 3:4 aspect ratio 53 | padding-bottom: 133.33%; 54 | } 55 | 56 | .immerse-section-tr__content { 57 | position: relative; 58 | z-index: 3; 59 | transform: translateZ(0); // fix z-index issue on Safari 60 | 61 | &::after, // overlay layer 62 | &::before { // section background 63 | content: ''; 64 | pointer-events: none; 65 | position: absolute; 66 | top: 0; 67 | left: 0; 68 | width: 100%; 69 | background: var(--color-bg); 70 | opacity: var(--immerse-section-tr-opacity, 0); 71 | pointer-events: none; 72 | } 73 | 74 | &::before { 75 | height: 100%; 76 | z-index: -1; 77 | } 78 | 79 | &::after { 80 | height: 100vh; 81 | transform: translateY(-100%); 82 | } 83 | } 84 | 85 | .immerse-section-tr--disabled .immerse-section-tr__content::before { 86 | opacity: 1; 87 | } 88 | } 89 | 90 | html:not(.js) .immerse-section-tr__content { 91 | background-color: var(--color-bg); 92 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_link-effects.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_link-effects 6 | Title: Link Effects 7 | Descr: A collection of link effects 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | // v1 13 | .link-fx-1 { 14 | position: relative; 15 | display: inline-flex; 16 | align-items: center; 17 | height: 32px; // !important - set fixed height 18 | padding: 0 6px; 19 | text-decoration: none; 20 | @include fontSmooth; 21 | 22 | .icon { 23 | position: absolute; 24 | right: 0; 25 | bottom: 0; 26 | transform: translateX(100%) rotate(90deg); 27 | font-size: 32px; // icon size = link size 👆 28 | 29 | circle { 30 | stroke-dasharray: 100; 31 | stroke-dashoffset: 100; 32 | transition: stroke-dashoffset .2s; 33 | } 34 | 35 | line { 36 | transition: transform .4s; 37 | transform-origin: 13px 15px; 38 | } 39 | 40 | line:last-child { 41 | transform-origin: 19px 15px; 42 | } 43 | } 44 | 45 | &::before { // border bottom 46 | content: ''; 47 | position: absolute; 48 | bottom: 0; 49 | left: 0; 50 | width: 100%; 51 | height: 1px; 52 | background-color: currentColor; 53 | transform-origin: right center; 54 | transition: transform .2s .1s; 55 | } 56 | 57 | &:hover { 58 | .icon { 59 | circle { 60 | stroke-dashoffset: 200; 61 | transition: stroke-dashoffset .2s .1s; 62 | } 63 | 64 | line { 65 | transform: rotate(-180deg); 66 | } 67 | 68 | line:last-child { 69 | transform: rotate(180deg); 70 | } 71 | } 72 | 73 | &::before { 74 | transform: translateX(17px) scaleX(0); 75 | transition: transform .2s; 76 | } 77 | } 78 | } 79 | 80 | // v2 81 | .link-fx-2 { 82 | position: relative; 83 | display: inline-block; 84 | padding: 4px 6px; 85 | color: var(--color-contrast-higher); 86 | text-decoration: none; 87 | background-image: linear-gradient(var(--color-contrast-higher), var(--color-contrast-higher)); 88 | background-size: 100% 1px; 89 | background-repeat: repeat-x; 90 | background-position: left bottom; 91 | will-change: background-size; 92 | transition: background-size .3s var(--ease-out); 93 | @include fontSmooth; 94 | 95 | &::after { 96 | content: attr(data-link-fx-clone); 97 | color: var(--color-bg); 98 | position: absolute; 99 | top: 0; 100 | left: 0; 101 | width: 100%; 102 | height: 100%; 103 | padding: inherit; 104 | will-change: clip-path, transform; 105 | clip-path: polygon(0% 100%, 100% 100%, 100% 100%, 0% 100%); 106 | transform: translateY(4px); 107 | transition: clip-path .3s, transform .3s; 108 | transition-timing-function: var(--ease-out); 109 | } 110 | 111 | &:hover { 112 | background-size: 100% 100%; 113 | 114 | &::after { 115 | clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); 116 | transform: translateY(0px); 117 | } 118 | } 119 | } 120 | 121 | // v3 122 | .link-fx-3 { 123 | position: relative; 124 | display: inline-flex; 125 | padding: 4px 6px; 126 | text-decoration: none; 127 | align-items: center; 128 | 129 | .icon { 130 | display: block; 131 | font-size: 12px; // icon size 132 | margin-left: 8px; 133 | position: relative; 134 | opacity: 0; 135 | visibility: hidden; 136 | will-change: transform; 137 | transform: translateY(10px); 138 | transition: opacity .3s, transform .3s var(--ease-out), visibility 0s .3s; 139 | 140 | line { 141 | transform-origin: 9px 6px; 142 | will-change: transform; 143 | transition: transform .3s var(--ease-out); 144 | } 145 | 146 | line:first-child { 147 | transform: rotate(20deg); 148 | } 149 | 150 | line:last-child { 151 | transform: rotate(-20deg); 152 | } 153 | } 154 | 155 | &::before { 156 | content: ''; 157 | position: absolute; 158 | bottom: 0; 159 | left: 0; 160 | width: calc(100% - 18px); // 18px = icon size (12px) + padding right (6px) 161 | height: 1px; 162 | background-color: currentColor; 163 | transition: .3s var(--ease-out); 164 | } 165 | 166 | &:hover { 167 | .icon { 168 | opacity: 1; 169 | visibility: visible; 170 | transform: translateY(0); 171 | transition: opacity .3s, transform .3s var(--ease-out); 172 | 173 | line:first-child, line:last-child { 174 | transform: rotate(0); 175 | } 176 | } 177 | 178 | &::before { 179 | width: 100%; 180 | } 181 | } 182 | } 183 | 184 | // v4 185 | .link-fx-4 { 186 | position: relative; 187 | display: inline-block; 188 | padding: 6px 10px; 189 | background-color: var(--color-contrast-lower); 190 | color: var(--color-contrast-higher); 191 | text-decoration: none; 192 | @include fontSmooth; 193 | 194 | &::before { 195 | content: attr(data-link-fx-clone); 196 | position: absolute; 197 | z-index: 1; 198 | top: 0; 199 | left: 0; 200 | width: 100%; 201 | height: 100%; 202 | display: flex; 203 | align-items: center; 204 | justify-content: center; 205 | background-color: var(--color-contrast-higher); 206 | color: var(--color-bg); 207 | will-change: clip-path; 208 | clip-path: polygon(0% 0%, 1px 0%, 1px 100%, 0% 100%); 209 | transition: clip-path .3s var(--ease-out); 210 | } 211 | 212 | &:hover { 213 | &::before { 214 | clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); 215 | } 216 | } 217 | } 218 | 219 | .link-fx-5 { 220 | display: inline-block; 221 | padding: 4px 0; 222 | text-decoration: none; 223 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='4' viewBox='0 0 16 4'%3E%3Cpath d='M0,3.5c4,0,4-3,8-3s4,3,8,3' fill='none' stroke='%232a6df4' opacity='0.5' stroke-miterlimit='10'/%3E%3C/svg%3E"); // 👈 edit stroke='%232a6df4' (last 6 digits - hexadecimal color) to change the color of the SVG decoration 224 | background-repeat: repeat-x; 225 | background-position: 0px 100%; 226 | background-size: 0; 227 | 228 | &:hover { 229 | background-size: 16px 4px; 230 | animation: link-fx-5-animation .4s linear infinite; 231 | } 232 | } 233 | 234 | @keyframes link-fx-5-animation { 235 | from { 236 | background-position: 0px 100%; 237 | } 238 | 239 | to { 240 | background-position: 16px 100%; 241 | } 242 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_list-v2.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_list-v2 6 | Title: List v2 7 | Descr: Custom list component 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | :root { 13 | --list-v2-bullet-size: 40px; 14 | --list-v2-bullet-font-size: 1rem; 15 | --list-v2-bullet-margin-right: 1rem; 16 | --list-v2-gap-y: var(--space-lg); /* list points gap */ 17 | } 18 | 19 | .list-v2, .text-component .list-v2 { 20 | padding-left: 0; 21 | list-style: none; 22 | 23 | > li:not(:last-child) { 24 | margin-bottom: var(--list-v2-gap-y); 25 | } 26 | } 27 | 28 | .list-v2__title { 29 | padding-left: calc(var(--list-v2-bullet-size) + var(--list-v2-bullet-margin-right)); 30 | } 31 | 32 | .list-v2__bullet { 33 | display: inline-flex; 34 | align-items: center; 35 | justify-content: center; 36 | flex-shrink: 0; 37 | 38 | width: var(--list-v2-bullet-size); 39 | height: var(--list-v2-bullet-size); 40 | 41 | margin-right: var(--list-v2-bullet-margin-right); 42 | margin-left: calc(-1 * var(--list-v2-bullet-size) - var(--list-v2-bullet-margin-right)); 43 | 44 | vertical-align: middle; 45 | position: relative; 46 | top: -0.1em; 47 | } 48 | 49 | .list-v2__content { 50 | margin-left: calc(var(--list-v2-bullet-size) + var(--list-v2-bullet-margin-right)); 51 | } 52 | 53 | /* ordered list */ 54 | .list-v2--ol, .text-component .list-v2--ol { 55 | counter-reset: list-items; 56 | 57 | > li { 58 | counter-increment: list-items; 59 | } 60 | 61 | .list-v2__bullet { 62 | border-radius: 50%; 63 | background-color: alpha(var(--color-primary), 0.2); 64 | 65 | color: var(--color-primary); 66 | font-size: var(--list-v2-bullet-font-size); 67 | font-weight: 500; 68 | 69 | &::before { 70 | content: counter(list-items); 71 | } 72 | } 73 | } 74 | 75 | /* unordered list */ 76 | .list-v2--ul, .text-component .list-v2--ul { 77 | --list-v2-bullet-size: 10px; 78 | 79 | .list-v2__bullet { 80 | border-radius: 50%; 81 | background-color: var(--color-primary); 82 | } 83 | } 84 | 85 | /* icons */ 86 | .list-v2--icons, .text-component .list-v2--icons { 87 | --list-v2-bullet-size: 48px; 88 | 89 | .list-v2__bullet { 90 | border-radius: 50%; 91 | background-color: alpha(var(--color-primary), 0.2); 92 | } 93 | 94 | .list-v2__icon { 95 | --size: 24px; 96 | color: var(--color-primary); /* icon color */ 97 | } 98 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_list.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_list 6 | Title: List 7 | Descr: Custom list component 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | :root { 13 | --list-space-y: 0.375em; // vertical gaps 14 | --list-offset: 1em; // sublist horizontal offset 15 | --list-line-height-multiplier: 1; // line-height multiplier 16 | } 17 | 18 | .list, .text-component .list { 19 | padding-left: 0; 20 | list-style: none; 21 | 22 | ul, ol { 23 | list-style: none; 24 | margin: 0; // reset 25 | margin-top: calc((var(--list-space-y) / 2) * var(--text-space-y-multiplier, 1)); 26 | padding-top: calc((var(--list-space-y) / 2) * var(--text-space-y-multiplier, 1)); 27 | padding-left: var(--list-offset); 28 | } 29 | 30 | li { 31 | padding-bottom: calc((var(--list-space-y) / 2) * var(--text-space-y-multiplier, 1)); 32 | margin-bottom: calc((var(--list-space-y) / 2) * var(--text-space-y-multiplier, 1)); 33 | line-height: calc(var(--body-line-height) * var(--list-line-height-multiplier)); 34 | } 35 | 36 | > li:last-child, ul > li:last-child, ol > li:last-child { 37 | margin-bottom: 0; 38 | } 39 | 40 | &:not(.list--border) > li:last-child, ul > li:last-child, ol > li:last-child { 41 | padding-bottom: 0; 42 | } 43 | } 44 | 45 | /* #region (ul + ol) */ 46 | .list--ul, .text-component .list--ul, 47 | .list--ol, .text-component .list--ol { 48 | --list-offset: calc(var(--list-bullet-size) + var(--list-bullet-margin-right)); 49 | 50 | ul, ol { 51 | padding-left: 0; 52 | } 53 | 54 | li { 55 | @supports (--css: variables) { 56 | padding-left: var(--list-offset) !important; 57 | } 58 | } 59 | 60 | li::before { 61 | display: inline-flex; 62 | justify-content: center; 63 | align-items: center; 64 | vertical-align: middle; 65 | position: relative; 66 | top: -0.1em; 67 | 68 | @supports (--css: variables) { 69 | width: var(--list-bullet-size) !important; 70 | height: var(--list-bullet-size) !important; 71 | margin-left: calc(var(--list-bullet-size) * -1) !important; 72 | left: calc(var(--list-bullet-margin-right) * -1) !important; 73 | } 74 | } 75 | } 76 | 77 | // unordered list 78 | .list--ul, .text-component .list--ul { 79 | --list-bullet-size: 7px; // dot width and height 80 | --list-bullet-margin-right: 12px; // gap between bullet and content 81 | 82 | > li { 83 | padding-left: 19px; // IE fallback 84 | } 85 | 86 | > li::before { // bullet 87 | content: ''; 88 | border-radius: 50%; 89 | color: var(--color-contrast-lower); // bullet color 90 | background-color: currentColor; 91 | 92 | // IE fallback 93 | width: 7px; 94 | height: 7px; 95 | margin-left: -7px; 96 | left: -12px; 97 | // end - IE fallback 98 | } 99 | 100 | ul li::before { 101 | background-color: transparent; 102 | box-shadow: inset 0 0 0 2px currentColor; 103 | } 104 | } 105 | 106 | // ordered list 107 | .list--ol, .text-component .list--ol { 108 | --list-bullet-size: 26px; // ⚠️ use px or rem units - circle width and height 109 | --list-bullet-margin-right: 6px; // ⚠️ use px or rem units - gap between circle and content 110 | --list-bullet-font-size: 14px; // ⚠️ use px or rem units - bullet font size 111 | counter-reset: list-items; 112 | 113 | > li { 114 | counter-increment: list-items; 115 | padding-left: 32px; // IE fallback 116 | } 117 | 118 | ol { 119 | counter-reset: list-items; 120 | } 121 | 122 | > li::before { 123 | content: counter(list-items); 124 | font-size: var(--list-bullet-font-size, 14px); 125 | background-color: var(--color-contrast-lower); 126 | color: var(--color-contrast-high); 127 | line-height: 1; 128 | border-radius: 50%; 129 | 130 | // IE fallback 131 | width: 26px; 132 | height: 26px; 133 | margin-left: -26px; 134 | left: -6px; 135 | // end - IE fallback 136 | } 137 | 138 | ol > li::before { 139 | background-color: transparent; 140 | box-shadow: inset 0 0 0 2px var(--color-contrast-lower); 141 | } 142 | } 143 | /* #endregion */ 144 | 145 | /* #region (border) */ 146 | .list--border, .text-component .list--border { // show border divider among list items 147 | li:not(:last-child) { 148 | border-bottom: 1px solid var(--color-contrast-lower); 149 | } 150 | 151 | ul, ol { 152 | border-top: 1px solid var(--color-contrast-lower); 153 | } 154 | } 155 | /* #endregion */ 156 | 157 | /* #region (icons) */ 158 | .list--icons, .text-component .list--icons { // use icons as bullet points 159 | --list-bullet-size: 24px; 160 | --list-bullet-margin-right: 8px; // gap between icon and text 161 | --list-offset: calc(var(--list-bullet-size) + var(--list-bullet-margin-right)); 162 | 163 | ul, ol { 164 | padding-left: 32px; // IE fallback 165 | 166 | @supports (--css: variables) { 167 | padding-left: var(--list-offset); 168 | } 169 | } 170 | } 171 | 172 | .list__icon { 173 | position: relative; 174 | 175 | // IE fallback 176 | width: 24px; 177 | height: 24px; 178 | margin-right: 8px; 179 | 180 | &:not(.top-0) { 181 | top: calc((1em * var(--body-line-height) - 24px) / 2); 182 | } 183 | // end - IE fallback 184 | 185 | @supports (--css: variables) { 186 | width: var(--list-bullet-size); 187 | height: var(--list-bullet-size); 188 | margin-right: var(--list-bullet-margin-right); 189 | 190 | &:not(.top-0) { 191 | top: calc((1em * var(--body-line-height) * var(--list-line-height-multiplier) - var(--list-bullet-size)) / 2); 192 | } 193 | } 194 | } 195 | /* #endregion */ -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_main-footer.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_main-footer 6 | Title: Main Footer 7 | Descr: Footer navigation 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .main-footer {} 13 | 14 | .main-footer__logo { 15 | display: inline-block; 16 | 17 | svg, img { 18 | display: block; 19 | } 20 | } 21 | 22 | .main-footer__link { 23 | color: var(--color-contrast-medium); 24 | text-decoration: none; 25 | 26 | &:hover { 27 | color: var(--color-contrast-high); 28 | text-decoration: underline; 29 | } 30 | } 31 | 32 | .main-footer__social { 33 | text-decoration: none; 34 | display: inline-block; 35 | color: var(--color-contrast-medium); 36 | 37 | &:hover { 38 | color: var(--color-contrast-high); 39 | } 40 | 41 | .icon { 42 | font-size: 1.2em; // icon size 43 | } 44 | 45 | @include breakpoint(md) { 46 | .icon { 47 | font-size: 1em; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_modal-window.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_modal-window 6 | Title: Modal Window 7 | Descr: A modal dialog used to display critical information 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .modal { 13 | position: fixed; 14 | z-index: var(--z-index-overlay, 15); 15 | width: 100%; 16 | height: 100%; 17 | left: 0; 18 | top: 0; 19 | opacity: 0; 20 | visibility: hidden; 21 | 22 | &:not(.modal--is-visible) { 23 | pointer-events: none; 24 | background-color: transparent; 25 | } 26 | } 27 | 28 | .modal--is-visible { 29 | opacity: 1; 30 | visibility: visible; 31 | } 32 | 33 | // close button 34 | .modal__close-btn { 35 | display: flex; 36 | flex-shrink: 0; 37 | border-radius: 50%; 38 | transition: .2s; 39 | 40 | .icon { 41 | display: block; 42 | margin: auto; 43 | } 44 | } 45 | 46 | .modal__close-btn--outer { // close button - outside the modal__content 47 | width: 48px; 48 | height: 48px; 49 | position: fixed; 50 | top: var(--space-sm); 51 | right: var(--space-sm); 52 | z-index: var(--z-index-fixed-element, 10); 53 | background-color: alpha(var(--color-black), 0.9); 54 | transition: .2s; 55 | 56 | .icon { 57 | color: var(--color-white); // icon color 58 | transition: transform .3s var(--ease-out-back); 59 | } 60 | 61 | &:hover { 62 | background-color: alpha(var(--color-black), 1); 63 | 64 | .icon { 65 | transform: scale(1.1); 66 | } 67 | } 68 | } 69 | 70 | .modal__close-btn--inner { // close button - inside the modal__content 71 | --size: 32px; 72 | width: var(--size); 73 | height: var(--size); 74 | background-color: var(--color-bg-light); 75 | box-shadow: var(--inner-glow), var(--shadow-sm); 76 | transition: .2s; 77 | 78 | .icon { 79 | color: inherit; // icon color 80 | } 81 | 82 | &:hover { 83 | background-color: var(--color-bg-lighter); 84 | box-shadow: var(--inner-glow), var(--shadow-md); 85 | } 86 | } 87 | 88 | // animations 89 | :root { 90 | --modal-transition-duration: 0.2s; // fallback (i.e., unless specified differently in the variations 👇) 91 | } 92 | 93 | @media (prefers-reduced-motion: no-preference) { 94 | .modal--animate-fade { 95 | --modal-transition-duration: 0.2s; 96 | transition: opacity var(--modal-transition-duration), background-color var(--modal-transition-duration), visibility 0s var(--modal-transition-duration); 97 | 98 | &.modal--is-visible { 99 | transition: opacity var(--modal-transition-duration), background-color var(--modal-transition-duration), visibility 0s; 100 | } 101 | } 102 | 103 | .modal--animate-scale, 104 | .modal--animate-translate-up, 105 | .modal--animate-translate-down, 106 | .modal--animate-translate-right, 107 | .modal--animate-translate-left { 108 | --modal-transition-duration: .2s; 109 | transition: opacity var(--modal-transition-duration), background-color var(--modal-transition-duration), visibility 0s var(--modal-transition-duration); 110 | 111 | .modal__content { 112 | will-change: transform; 113 | transition: transform var(--modal-transition-duration) var(--ease-out); 114 | } 115 | 116 | &.modal--is-visible { 117 | transition: opacity var(--modal-transition-duration), background-color var(--modal-transition-duration), visibility 0s; 118 | 119 | .modal__content { 120 | transform: scale(1); // reset all transformations 121 | } 122 | } 123 | } 124 | 125 | .modal--animate-slide-up, 126 | .modal--animate-slide-down, 127 | .modal--animate-slide-right, 128 | .modal--animate-slide-left { 129 | --modal-transition-duration: 0.3s; 130 | transition: opacity 0s var(--modal-transition-duration), background-color var(--modal-transition-duration), visibility 0s var(--modal-transition-duration); 131 | 132 | .modal__content { 133 | will-change: transform; 134 | transition: transform var(--modal-transition-duration) var(--ease-out); 135 | } 136 | 137 | &.modal--is-visible { 138 | transition: background-color var(--modal-transition-duration), visibility 0s; 139 | 140 | .modal__content { 141 | transform: scale(1); // reset all transformations 142 | } 143 | } 144 | } 145 | 146 | // scale 147 | .modal--animate-scale { 148 | .modal__content { 149 | transform: scale(0.95); 150 | } 151 | } 152 | 153 | // translate 154 | .modal--animate-translate-up { 155 | .modal__content { 156 | transform: translateY(40px); 157 | } 158 | } 159 | 160 | .modal--animate-translate-down { 161 | .modal__content { 162 | transform: translateY(-40px); 163 | } 164 | } 165 | 166 | .modal--animate-translate-right { 167 | .modal__content { 168 | transform: translateX(-40px); 169 | } 170 | } 171 | 172 | .modal--animate-translate-left { 173 | .modal__content { 174 | transform: translateX(40px); 175 | } 176 | } 177 | 178 | // slide 179 | .modal--animate-slide-up { 180 | .modal__content { 181 | transform: translateY(100%); 182 | } 183 | } 184 | 185 | .modal--animate-slide-down { 186 | .modal__content { 187 | transform: translateY(-100%); 188 | } 189 | } 190 | 191 | .modal--animate-slide-right { 192 | .modal__content { 193 | transform: translateX(-100%); 194 | } 195 | } 196 | 197 | .modal--animate-slide-left { 198 | .modal__content { 199 | transform: translateX(100%); 200 | } 201 | } 202 | } 203 | 204 | // load content - optional 205 | .modal--is-loading { 206 | .modal__content { 207 | visibility: hidden; 208 | } 209 | 210 | .modal__loader { 211 | display: flex; 212 | } 213 | } 214 | 215 | .modal__loader { // loader icon 216 | position: fixed; 217 | top: 0; 218 | left: 0; 219 | width: 100%; 220 | height: 100%; 221 | justify-content: center; 222 | align-items: center; 223 | display: none; 224 | pointer-events: none; 225 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_newsletter.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_newsletter 6 | Title: Newsletter 7 | Descr: Newsletter form template 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .newsletter { 13 | position: relative; 14 | z-index: 1; 15 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_notice.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_notice 6 | Title: Notice 7 | Descr: Modeless notice banner, visible by default 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .notice { 13 | position: fixed; 14 | width: 100%; 15 | pointer-events: none; 16 | z-index: var(--z-index-fixed-element, 10); 17 | } 18 | 19 | .notice__banner { 20 | pointer-events: auto; 21 | } 22 | 23 | .notice__close-btn { 24 | --size: 2em; 25 | display: flex; 26 | width: var(--size); 27 | height: var(--size); 28 | flex-shrink: 0; 29 | justify-content: center; 30 | align-items: center; 31 | border-radius: 50%; 32 | background-color: alpha(var(--color-contrast-higher), 0.85); 33 | color: var(--color-bg); 34 | transition: .2s; 35 | 36 | &:hover { 37 | background-color: var(--color-contrast-higher); 38 | } 39 | 40 | .icon { 41 | --size: 16px; 42 | } 43 | } 44 | 45 | .notice--hide { 46 | opacity: 0; 47 | visibility: hidden; 48 | } 49 | 50 | @media screen and (prefers-reduced-motion: no-preference) { 51 | .notice { 52 | transition: opacity .3s, visibility 0s .3s; 53 | } 54 | 55 | .notice__banner { 56 | transition: transform .3s; 57 | } 58 | 59 | .notice--hide { 60 | .notice__banner { 61 | transform: translateY(20px); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_pagination.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_pagination 6 | Title: Pagination 7 | Descr: Component used to navigate through pages of related content 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .pagination {} 13 | 14 | .pagination__list > li { 15 | display: inline-block; // flex fallback 16 | } 17 | 18 | // --split - push first + last item to sides 19 | .pagination--split { 20 | .pagination__list { 21 | width: 100%; 22 | 23 | > *:first-child { 24 | margin-right: auto; 25 | } 26 | 27 | > *:last-child { 28 | margin-left: auto; 29 | } 30 | } 31 | } 32 | 33 | .pagination__item { 34 | display: inline-block; // flex fallback 35 | display: inline-flex; 36 | height: 100%; 37 | align-items: center; 38 | padding: var(--space-xs) calc(1.355 * var(--space-xs)); 39 | 40 | white-space: nowrap; 41 | line-height: 1; 42 | border-radius: var(--radius-md); 43 | 44 | text-decoration: none; 45 | color: var(--color-contrast-high); 46 | @include fontSmooth; 47 | 48 | will-change: transform; 49 | transition: .2s; 50 | 51 | &:hover:not(.pagination__item--selected):not(.pagination__item--ellipsis) { 52 | background-color: alpha(var(--color-contrast-higher), 0.1); 53 | } 54 | 55 | &:active { 56 | transform: translateY(2px); 57 | } 58 | } 59 | 60 | .pagination__item--selected { 61 | background-color: var(--color-contrast-higher); 62 | color: var(--color-bg); 63 | box-shadow: var(--shadow-sm); 64 | } 65 | 66 | .pagination__item--disabled { 67 | opacity: 0.5; 68 | pointer-events: none; 69 | } 70 | 71 | // --jumper 72 | .pagination__jumper { 73 | .form-control { 74 | width: 3em; 75 | margin-right: var(--space-xs); 76 | } 77 | 78 | em { 79 | flex-shrink: 0; 80 | white-space: nowrap; 81 | } 82 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_radio-switch.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_radio-switch 6 | Title: Radio Switch 7 | Descr: Custom radio toggle 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | :root { 13 | // style 14 | --radio-switch-width: 186px; 15 | --radio-switch-height: 46px; 16 | --radio-switch-padding: 3px; 17 | --radio-switch-radius: 50em; 18 | 19 | // animation 20 | --radio-switch-animation-duration: 0.3s; 21 | } 22 | 23 | .radio-switch { 24 | position: relative; 25 | display: inline-block; // flexbox fallback 26 | display: inline-flex; 27 | padding: var(--radio-switch-padding); 28 | border-radius: calc(var(--radio-switch-radius) * 1.4); 29 | background-color: var(--color-bg-darker); 30 | 31 | &:focus-within, &:active { 32 | box-shadow: 0 0 0 2px alpha(var(--color-contrast-higher), 0.15); // focus effect 33 | } 34 | } 35 | 36 | .radio-switch__item { 37 | position: relative; 38 | display: inline-block; // flexbox fallback 39 | height: calc(var(--radio-switch-height) - 2*var(--radio-switch-padding)); 40 | width: calc(var(--radio-switch-width)*0.5 - var(--radio-switch-padding)); 41 | } 42 | 43 | .radio-switch__label { 44 | position: relative; 45 | z-index: 2; 46 | display: flex; 47 | height: 100%; 48 | align-items: center; 49 | justify-content: center; 50 | border-radius: var(--radio-switch-radius); 51 | cursor: pointer; 52 | font-size: var(--text-sm); 53 | user-select: none; 54 | transition: all var(--radio-switch-animation-duration); 55 | 56 | .radio-switch__input:checked ~ & { 57 | color: var(--color-white); 58 | } 59 | 60 | .radio-switch__input:focus ~ & { // focus effect in browsers not supporting :focus-within 61 | background-color: lightness(var(--color-primary), 0.6); 62 | } 63 | 64 | :not(*):focus-within, // trick to detect :focus-within support -> https://css-tricks.com/using-feature-detection-conditionals-and-groups-with-selectors/ 65 | .radio-switch__input:focus ~ & { // reset focus style for browsers supporting :focus-within 66 | background-color: transparent; 67 | } 68 | } 69 | 70 | .radio-switch__marker { 71 | position: absolute; 72 | z-index: 1; 73 | top: 0; 74 | left: -100%; 75 | border-radius: var(--radio-switch-radius); 76 | background-color: var(--color-primary); 77 | height: calc(var(--radio-switch-height) - 2*var(--radio-switch-padding)); 78 | width: calc(var(--radio-switch-width)*0.5 - var(--radio-switch-padding)); 79 | box-shadow: var(--shadow-md); 80 | transition: transform var(--radio-switch-animation-duration); 81 | 82 | .radio-switch__input:checked ~ & { 83 | transform: translateX(100%); 84 | } 85 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_radios-checkboxes.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_radios-checkboxes 6 | Title: Radios and Checkboxes 7 | Descr: Custom radio and checkbox buttons 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | :root { 13 | // radios and checkboxes 14 | --checkbox-radio-size: 18px; 15 | --checkbox-radio-gap: var(--space-xxs); // gap between button and label 16 | --checkbox-radio-border-width: 1px; 17 | --checkbox-radio-line-height: var(--body-line-height); 18 | 19 | // radio buttons 20 | --radio-marker-size: 8px; 21 | 22 | // checkboxes 23 | --checkbox-marker-size: 12px; 24 | --checkbox-radius: 4px; 25 | } 26 | 27 | // hide native buttons 28 | .radio, 29 | .checkbox { 30 | position: absolute; 31 | padding: 0; 32 | margin: 0; 33 | margin-top: calc((1em * var(--checkbox-radio-line-height) - var(--checkbox-radio-size)) / 2); 34 | opacity: 0; 35 | height: var(--checkbox-radio-size); 36 | width: var(--checkbox-radio-size); 37 | pointer-events: none; 38 | } 39 | 40 | // label 41 | .radio + label, 42 | .checkbox + label { 43 | display: inline-block; 44 | line-height: var(--checkbox-radio-line-height); 45 | user-select: none; 46 | cursor: pointer; 47 | padding-left: calc(var(--checkbox-radio-size) + var(--checkbox-radio-gap)); 48 | } 49 | 50 | // custom inputs - basic style 51 | .radio + label::before, 52 | .checkbox + label::before { 53 | content: ''; 54 | box-sizing: border-box; 55 | display: inline-block; 56 | position: relative; 57 | vertical-align: middle; 58 | top: -0.1em; 59 | margin-left: calc(-1 * (var(--checkbox-radio-size) + var(--checkbox-radio-gap))); 60 | flex-shrink: 0; 61 | width: var(--checkbox-radio-size); 62 | height: var(--checkbox-radio-size); 63 | background-color: var(--color-bg); 64 | border-width: var(--checkbox-radio-border-width); 65 | border-color: alpha(var(--color-contrast-low), 0.65); 66 | border-style: solid; 67 | box-shadow: var(--shadow-xs); 68 | background-repeat: no-repeat; 69 | background-position: center; 70 | margin-right: var(--checkbox-radio-gap); 71 | transition: transform .2s, border .2s; 72 | } 73 | 74 | // :hover 75 | .radio:not(:checked):not(:focus) + label:hover::before, 76 | .checkbox:not(:checked):not(:focus) + label:hover::before { 77 | border-color: alpha(var(--color-contrast-low), 1); 78 | } 79 | 80 | // radio only style 81 | .radio + label::before { 82 | border-radius: 50%; 83 | } 84 | 85 | // checkbox only style 86 | .checkbox + label::before { 87 | border-radius: var(--checkbox-radius); 88 | } 89 | 90 | // :checked 91 | .radio:checked + label::before, 92 | .checkbox:checked + label::before { 93 | background-color: var(--color-primary); 94 | box-shadow: var(--shadow-xs); 95 | border-color: var(--color-primary); 96 | transition: transform .2s; 97 | } 98 | 99 | // :active 100 | .radio:active + label::before, 101 | .checkbox:active + label::before { 102 | transform: scale(0.8); 103 | transition: transform .2s; 104 | } 105 | 106 | // :checked:active 107 | .radio:checked:active + label::before, 108 | .checkbox:checked:active + label::before { 109 | transform: none; 110 | transition: none; 111 | } 112 | 113 | // radio button icon 114 | .radio:checked + label::before { 115 | background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cg class='nc-icon-wrapper' fill='%23ffffff'%3E%3Ccircle cx='8' cy='8' r='8' fill='%23ffffff'%3E%3C/circle%3E%3C/g%3E%3C/svg%3E"); 116 | background-size: var(--radio-marker-size); 117 | } 118 | 119 | // checkbox button icon 120 | .checkbox:checked + label::before { 121 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpolyline points='1 6.5 4 9.5 11 2.5' fill='none' stroke='%23FFFFFF' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'/%3E%3C/svg%3E"); 122 | background-size: var(--checkbox-marker-size); 123 | } 124 | 125 | // :focus 126 | .radio:checked:active + label::before, 127 | .checkbox:checked:active + label::before, 128 | .radio:focus + label::before, 129 | .checkbox:focus + label::before { 130 | border-color: var(--color-primary); 131 | box-shadow: 0 0 0 3px alpha(var(--color-primary), 0.2); 132 | } 133 | 134 | // --radio--bg, --checkbox--bg -> variation with background color 135 | .radio--bg + label, .checkbox--bg + label { 136 | padding: var(--space-xxxxs) var(--space-xxxs); 137 | padding-left: calc(var(--checkbox-radio-size) + var(--checkbox-radio-gap) + var(--space-xxxs)); 138 | border-radius: var(--radius-md); 139 | transition: background .2s; 140 | } 141 | 142 | .radio--bg + label:hover, .checkbox--bg + label:hover { 143 | background-color: alpha(var(--color-contrast-higher), 0.075); 144 | } 145 | 146 | .radio--bg:active + label, 147 | .checkbox--bg:active + label, 148 | .radio--bg:focus + label, 149 | .checkbox--bg:focus + label { 150 | background-color: alpha(var(--color-primary), 0.1); 151 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_reading-progressbar.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_reading-progressbar 6 | Title: Reading Progress Bar 7 | Descr: A bar indicator displaying the current reading progress 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .reading-progressbar { 13 | position: fixed; 14 | z-index: var(--z-index-fixed-element, 10); 15 | top: 0; 16 | left: 0; 17 | width: 100%; 18 | height: 5px; 19 | color: var(--color-primary); // fill color 20 | pointer-events: none; 21 | display: none; 22 | transition: transform 0.2s; 23 | } 24 | 25 | .reading-progressbar--is-out { 26 | transform: translateY(-100%); 27 | } 28 | 29 | .reading-progressbar--is-active { // if JS = enabled && content is scrollable 30 | display: block; 31 | } 32 | 33 | .reading-progressbar::-webkit-progress-bar { 34 | background-color: transparent; 35 | } 36 | 37 | .reading-progressbar::-webkit-progress-value { 38 | background-color: currentColor; 39 | } 40 | 41 | .reading-progressbar::-moz-progress-bar { 42 | background-color: currentColor; 43 | } 44 | 45 | .reading-progressbar__fallback { 46 | // fallback for brawsers not supporting the element 47 | position: absolute; 48 | left: 0; 49 | top: 0; 50 | height: 100%; 51 | background-color: currentColor; 52 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_reveal-effects.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_reveal-effects 6 | Title: Reveal Effects 7 | Descr: A collection of reveal effects targeting specific elements as they enter the viewport 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | :root { 12 | --reveal-fx-duration: 0.6s; 13 | --reveal-fx-timing-function: var(--ease-out); 14 | } 15 | 16 | .js { 17 | .reveal-fx { 18 | opacity: 0; 19 | transition: opacity, transform var(--reveal-fx-timing-function); 20 | transition-duration: var(--reveal-fx-duration); 21 | 22 | &::before { // never visible - used to check MQ in JS 23 | display: none; 24 | content: 'reveal-fx'; 25 | } 26 | } 27 | 28 | .reveal-fx--translate, .reveal-fx--translate-up { 29 | transform: translateY(50px); 30 | } 31 | 32 | .reveal-fx--translate-right { 33 | transform: translateX(-50px); 34 | } 35 | 36 | .reveal-fx--translate-left { 37 | transform: translateX(50px); 38 | } 39 | 40 | .reveal-fx--translate-down { 41 | transform: translateY(-50px); 42 | } 43 | 44 | .reveal-fx--scale { 45 | transform: scale(0.8); 46 | } 47 | 48 | .reveal-fx--scale-up { 49 | transform: translateY(50px) scale(0.8); 50 | } 51 | 52 | .reveal-fx--scale-right { 53 | transform: translateX(-50px) scale(0.8); 54 | } 55 | 56 | .reveal-fx--scale-left { 57 | transform: translateX(50px) scale(0.8); 58 | } 59 | 60 | .reveal-fx--scale-down { 61 | transform: translateY(-50px) scale(0.8); 62 | } 63 | 64 | .reveal-fx--rotate, .reveal-fx--rotate-down, .reveal-fx--rotate-right, .reveal-fx--rotate-left, .reveal-fx--rotate-up { // ⚠️ add class to parent 65 | perspective: 1000px; 66 | 67 | > * { 68 | transition: transform var(--reveal-fx-duration) var(--reveal-fx-timing-function); 69 | backface-visibility: hidden; 70 | } 71 | } 72 | 73 | .reveal-fx--rotate, .reveal-fx--rotate-down { 74 | > * { 75 | transform-origin: top; 76 | transform: rotateX(-45deg); 77 | } 78 | } 79 | 80 | .reveal-fx--rotate-right { 81 | > * { 82 | transform-origin: left center; 83 | transform: rotateY(45deg); 84 | } 85 | } 86 | 87 | .reveal-fx--rotate-left { 88 | > * { 89 | transform-origin: right center; 90 | transform: rotateY(-45deg); 91 | } 92 | } 93 | 94 | .reveal-fx--rotate-up { 95 | > * { 96 | transform-origin: bottom; 97 | transform: rotateX(45deg); 98 | } 99 | } 100 | 101 | .reveal-fx--text-mask { // reveal sigle words/letter 102 | overflow: hidden; 103 | 104 | > * { 105 | display: inline-block; 106 | transform: translateY(100%); 107 | transition: transform var(--reveal-fx-duration) var(--reveal-fx-timing-function); 108 | will-change: transform; 109 | } 110 | } 111 | 112 | [class*="reveal-fx--translate"], [class*="reveal-fx--scale"] { 113 | will-change: opacity, transform; 114 | } 115 | 116 | .reveal-fx--text-mask > *, [class*="reveal-fx--rotate"] > * { 117 | will-change: transform; 118 | } 119 | 120 | // clip path effects 121 | .reveal-fx--clip-x, 122 | .reveal-fx--clip-y { 123 | > * { 124 | transition: opacity, clip-path var(--ease-out); 125 | transition-duration: var(--reveal-fx-duration); 126 | } 127 | } 128 | 129 | .reveal-fx--clip-x { 130 | > * { 131 | clip-path: polygon(10% 0%, 90% 0%, 90% 100%, 10% 100%); 132 | } 133 | } 134 | 135 | .reveal-fx--clip-y { 136 | > * { 137 | clip-path: polygon(0% 50%, 100% 50%, 100% 100%, 0% 100%); 138 | } 139 | } 140 | 141 | .reveal-fx--is-visible { // reveal element when it enters the viewport 142 | opacity: 1; 143 | 144 | &[class*="reveal-fx--translate"], 145 | &[class*="reveal-fx--scale"], 146 | &[class*="reveal-fx--rotate"] > *, 147 | &.reveal-fx--text-mask > * { 148 | transform: translate(0); // reset all transformations 149 | } 150 | 151 | &.reveal-fx--clip-x, 152 | &.reveal-fx--clip-y { 153 | > * { 154 | opacity: 1; 155 | clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); 156 | } 157 | } 158 | } 159 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_search-input.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_search-input 6 | Title: Search input 7 | Descr: Search input field with custom button 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | :root { 13 | --search-input-btn-width: 2.2em; 14 | --search-input-icon-size: 1em; 15 | --search-input-shortcut-margin: 0.325em; /* gap between the shortcut badge and the input edges */ 16 | } 17 | 18 | .search-input { 19 | position: relative; 20 | } 21 | 22 | .search-input__input { 23 | width: 100%; 24 | height: 100%; 25 | 26 | &::-webkit-search-decoration, 27 | &::-webkit-search-cancel-button, 28 | &::-webkit-search-results-button, 29 | &::-webkit-search-results-decoration { 30 | -webkit-appearance:none; 31 | } 32 | 33 | &::-ms-clear, 34 | &::-ms-reveal { 35 | display: none; 36 | width: 0; 37 | height: 0; 38 | } 39 | 40 | .search-input--icon-right & { 41 | padding-right: var(--search-input-btn-width); 42 | } 43 | 44 | .search-input--icon-left & { 45 | padding-left: var(--search-input-btn-width); 46 | } 47 | } 48 | 49 | .search-input__btn { 50 | @include reset; 51 | position: absolute; 52 | top: 0; 53 | right: 0; 54 | display: flex; 55 | justify-content: center; 56 | align-items: center; 57 | height: 100%; 58 | width: var(--search-input-btn-width); 59 | 60 | &:active .icon { 61 | transform: translateY(2px); 62 | } 63 | 64 | .icon { 65 | display: block; 66 | --size: var(--search-input-icon-size); 67 | margin-left: auto; 68 | margin-right: auto; 69 | color: var(--color-contrast-low); /* icon color */ 70 | transition: .2s; 71 | } 72 | 73 | .search-input--icon-left & { 74 | left: 0; 75 | right: auto; 76 | pointer-events: none; 77 | } 78 | } 79 | 80 | .search-input__btn:focus .icon, 81 | .search-input .search-input__input:focus + .search-input__btn .icon { 82 | color: var(--color-primary); /* active icon color */ 83 | } 84 | 85 | /* --shortcut */ 86 | .search-input__shortcut { 87 | position: absolute; 88 | right: var(--search-input-shortcut-margin); 89 | top: var(--search-input-shortcut-margin); 90 | height: calc(100% - var(--search-input-shortcut-margin)*2); 91 | display: flex; 92 | align-items: center; 93 | 94 | background-color: var(--color-bg); 95 | border: 1px solid var(--color-contrast-lower); 96 | border-radius: var(--radius-sm); 97 | 98 | --space-unit: 1em; 99 | padding: 0 var(--space-xxxs); 100 | 101 | line-height: 1; 102 | color: var(--color-contrast-medium); 103 | } 104 | 105 | .search-input:focus-within .search-input__shortcut { 106 | display: none; 107 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_skip-link.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_skip-link 6 | Title: Skip Link 7 | Descr: Accessibility feature that allows users to jump to the main content of the page 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .skip-link { 13 | position: absolute; 14 | z-index: var(--z-index-fixed-element, 10); 15 | top: 0; 16 | left: 0; 17 | display: inline-block; 18 | padding: var(--space-sm) var(--space-md); 19 | background-color: var(--color-bg-light); 20 | box-shadow: var(--shadow-lg); 21 | @include fontSmooth; 22 | 23 | // hide 24 | clip: rect(1px, 1px, 1px, 1px); 25 | clip-path: inset(50%); 26 | 27 | &:focus, &.skip-link--focus { 28 | // show 29 | clip: auto; 30 | clip-path: none; 31 | outline: 3px solid alpha(var(--color-primary), 0.2); 32 | } 33 | } 34 | 35 | // optional - enable smooth scrolling 36 | @media screen and (prefers-reduced-motion: no-preference) { 37 | html { 38 | scroll-behavior: smooth; 39 | } 40 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_social-sharing.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_social-sharing 6 | Title: Social Sharing 7 | Descr: Social sharing plugin 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .sharebar {} 13 | 14 | .sharebar__btn { 15 | --size: 60px; 16 | width: var(--size); 17 | height: var(--size); 18 | display: flex; 19 | 20 | background: alpha(var(--color-contrast-higher), 0.1); 21 | border-radius: 50%; 22 | 23 | transition: .2s; 24 | 25 | .icon { 26 | --size: 24px; 27 | display: block; 28 | margin: auto; 29 | color: var(--color-contrast-high); 30 | 31 | transition: color .2s; 32 | } 33 | 34 | &:hover { 35 | background-color: alpha(var(--color-contrast-higher), 0.075); 36 | box-shadow: var(--shadow-sm); 37 | 38 | .icon { 39 | color: var(--color-contrast-higher); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_sticky-hero.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_sticky-hero 6 | Title: Sticky Hero 7 | Descr: A sticky hero section that reveals its content on scroll 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .sticky-hero { 13 | position: relative; 14 | z-index: 1; 15 | } 16 | 17 | .sticky-hero__media { // img or video 18 | position: relative; // fallback 19 | position: sticky; 20 | z-index: 1; 21 | top: 0; 22 | width: 100%; 23 | height: 100vh; 24 | overflow: hidden; 25 | 26 | background-size: cover; 27 | background-position: center; 28 | background-repeat: no-repeat; 29 | 30 | transition: transform 0.5s var(--ease-in-out); 31 | 32 | transform: translateZ(0); // fix issue on iOS 33 | } 34 | 35 | .sticky-hero--overlay-layer .sticky-hero__media::after { // overlay layer 36 | content: ''; 37 | position: absolute; 38 | top: 0; 39 | left: 0; 40 | height: 100%; 41 | width: 100%; 42 | opacity: 0; 43 | background-color: var(--color-bg); 44 | transition: opacity 1s; 45 | } 46 | 47 | .sticky-hero--media-is-fixed.sticky-hero--overlay-layer .sticky-hero__media::after { 48 | opacity: 0.65; 49 | } 50 | 51 | .sticky-hero--media-is-fixed.sticky-hero--scale .sticky-hero__media { 52 | transform: scale(0.9); 53 | } 54 | 55 | .sticky-hero__video { 56 | position: absolute; 57 | top: 0; 58 | left: 0; 59 | height: 100%; 60 | width: 100%; 61 | 62 | video { 63 | position: absolute; 64 | top: 50%; 65 | left: 50%; 66 | transform: translateX(-50%) translateY(-50%); 67 | display: block; 68 | min-height: 100%; 69 | min-width: 100%; 70 | height: auto; 71 | width: auto; 72 | max-width: none; 73 | } 74 | } 75 | 76 | .sticky-hero__content { 77 | position: relative; 78 | z-index: 2; 79 | 80 | height: 100vh; 81 | display: flex; 82 | justify-content: center; 83 | align-items: center; 84 | 85 | transform: translateZ(0); // fix issue on iOS 86 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_testimonial.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_testimonial 6 | Title: Testimonial 7 | Descr: A testimonial quote 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | .testimonial {} 13 | 14 | .testimonial__block-wrapper { 15 | position: relative; 16 | 17 | blockquote { 18 | position: relative; 19 | z-index: 1; 20 | } 21 | 22 | .icon { 23 | position: absolute; 24 | top: -0.5em; 25 | left: -0.5em; 26 | } 27 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_text-points.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_text-points 6 | Title: Text Points 7 | Descr: A list of text components 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | 12 | :root { 13 | --text-points-bullet-size: 1.2em; // bullet (circle) 14 | --text-points-bullet-text-scale: 0.6; // bullet font-size scale factor 15 | } 16 | 17 | .text-points { 18 | --text-unit: 1em; // use Em units 19 | font-size: 0.875em; 20 | } 21 | 22 | .text-points__item { 23 | color: var(--color-contrast-medium); 24 | 25 | .text-component { 26 | --line-height-multiplier: 1.15; // see framework > _typography.scss 27 | } 28 | } 29 | 30 | .text-points--counter, 31 | .text-points--letter, 32 | .text-points--icon { 33 | .text-points__title { 34 | position: relative; 35 | padding-left: calc(var(--text-points-bullet-size) + var(--space-xxxs)); 36 | 37 | &::before { // bullet 38 | position: absolute; 39 | top: 0; 40 | left: 0; 41 | font-size: calc(1em * var(--text-points-bullet-text-scale)); 42 | height: calc(var(--text-points-bullet-size)/var(--text-points-bullet-text-scale)); 43 | width: calc(var(--text-points-bullet-size)/var(--text-points-bullet-text-scale)); 44 | line-height: calc(var(--text-points-bullet-size)/var(--text-points-bullet-text-scale)); 45 | font-weight: medium; 46 | text-align: center; 47 | background-color: var(--color-contrast-lower); 48 | color: var(--color-contrast-medium); 49 | border-radius: 50%; 50 | } 51 | 52 | @include breakpoint(lg) { 53 | padding-left: 0; 54 | 55 | &::before { 56 | transform: translateX(-100%); 57 | left: -8px; 58 | } 59 | } 60 | } 61 | } 62 | 63 | // --counter -> bullet = number 64 | .text-points--counter { 65 | .text-points__item { 66 | counter-increment: text-points; // used to set the counter content 67 | } 68 | 69 | .text-points__title { 70 | &::before { 71 | content: counter(text-points); 72 | } 73 | } 74 | } 75 | 76 | // --letter -> bullet = letter 77 | .text-points--letter { 78 | .text-points__title { 79 | &::before { 80 | content: '?'; 81 | } 82 | } 83 | } 84 | 85 | // --icon -> bullet = icon 86 | .text-points--icon { 87 | .text-points__title { 88 | &::before { 89 | content: ''; 90 | mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12,0A12,12,0,1,0,24,12,12.013,12.013,0,0,0,12,0Zm2.658,18.284c-.661.26-2.952,1.354-4.272.191a1.676,1.676,0,0,1-.59-1.318,15.978,15.978,0,0,1,.919-3.957,5.7,5.7,0,0,0,.231-1.313c0-.7-.266-.887-.987-.887a3.31,3.31,0,0,0-1.095.257l.195-.8a7.64,7.64,0,0,1,2.621-.71c1.269,0,2.2.633,2.2,1.837A5.585,5.585,0,0,1,13.7,12.96l-.73,2.582c-.151.522-.424,1.673,0,2.014a2.214,2.214,0,0,0,1.887-.071ZM13.452,8a1.5,1.5,0,1,1,1.5-1.5A1.5,1.5,0,0,1,13.452,8Z'/%3E%3C/svg%3E"); 91 | background: var(--color-contrast-lower); // icon color 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_1_vertical-timeline.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | /* -------------------------------- 4 | 5 | File#: _1_vertical-timeline 6 | Title: Vertical Timeline 7 | Descr: A vertical timeline used to display a sequence of events/steps 8 | Usage: codyhouse.co/license 9 | 10 | -------------------------------- */ 11 | :root { 12 | --v-timeline-marker-size: 16px; // dot indicator size 13 | --v-timeline-track-width: 2px; // vertical track (line) width 14 | --v-timeline-triangle-size: 12px; // triangle indicator size 15 | --v-timeline-sections-gap: var(--space-lg); // gap between sections (section = marker + item/s) 16 | --v-timeline-items-gap: var(--space-sm); // gap between items (if there are more than one within same date) 17 | } 18 | 19 | .v-timeline { 20 | position: relative; 21 | padding: var(--space-lg) 0; // y padding 22 | 23 | &::before { // track 24 | content: ''; 25 | position: absolute; 26 | top: 0; 27 | left: calc((var(--v-timeline-marker-size) - var(--v-timeline-track-width))*0.5); 28 | height: 100%; 29 | width: var(--v-timeline-track-width); 30 | background-color: alpha(var(--color-contrast-higher), 0.1); 31 | } 32 | } 33 | 34 | .v-timeline__section { 35 | position: relative; 36 | display: flex; 37 | 38 | &:not(:last-of-type) { 39 | margin-bottom: var(--v-timeline-sections-gap); 40 | } 41 | } 42 | 43 | .v-timeline__marker { 44 | flex-shrink: 0; 45 | justify-content: center; 46 | align-items: center; 47 | display: flex; 48 | position: relative; 49 | height: var(--v-timeline-marker-size); 50 | width: var(--v-timeline-marker-size); 51 | border-radius: 50%; 52 | margin-right: calc(var(--v-timeline-triangle-size) + var(--space-xxs)); 53 | } 54 | 55 | .v-timeline__item { 56 | position: relative; 57 | top: calc(0.5 * var(--v-timeline-marker-size)); 58 | flex-grow: 1; 59 | 60 | &::before { // triangle indicator 61 | content: ''; 62 | position: absolute; 63 | top: 0; 64 | left: calc(-1 * var(--v-timeline-triangle-size) + 1px); 65 | height: var(--v-timeline-triangle-size); 66 | width: var(--v-timeline-triangle-size); 67 | background-color: inherit; 68 | clip-path: polygon(0% 0%, 100% 0%, 100% 100%); 69 | } 70 | 71 | &:not(:last-child) { 72 | margin-bottom: var(--v-timeline-items-gap); // gap between timeline items 73 | } 74 | 75 | &:not(:first-child) { 76 | .v-timeline__date { 77 | display: none; // hide date if not first item 78 | } 79 | 80 | &::before { 81 | display: none; // hide triangle if not first item 82 | } 83 | } 84 | } 85 | 86 | .v-timeline__date-value { // date label 87 | color: var(--color-contrast-medium); 88 | font-size: var(--text-sm); 89 | text-transform: uppercase; 90 | letter-spacing: 0.1em; 91 | } 92 | 93 | @include breakpoint(md, "not all") { // style applied only before breakpoint 'md' 94 | .v-timeline__item:first-child { 95 | border-top-left-radius: 0; 96 | } 97 | } 98 | 99 | @include breakpoint(md) { // edit timeline layout 100 | .v-timeline::before { // track 101 | left: calc(50% - var(--v-timeline-track-width)/2); 102 | } 103 | 104 | .v-timeline__section { 105 | width: calc(50% + var(--v-timeline-marker-size)/2); 106 | 107 | &:nth-child(odd) { 108 | flex-direction: row-reverse; 109 | 110 | .v-timeline__marker { 111 | margin-right: 0; 112 | margin-left: calc(var(--v-timeline-triangle-size) + var(--space-xxs)); 113 | } 114 | 115 | .v-timeline__item { 116 | &::before { // push triangle to the right 117 | left: auto; 118 | right: calc(-1 * var(--v-timeline-triangle-size) + 1px); 119 | transform: scaleX(-1); 120 | } 121 | 122 | &:first-child { 123 | border-top-right-radius: 0; 124 | } 125 | } 126 | 127 | .v-timeline__date { 128 | right: calc(-2 * (var(--v-timeline-triangle-size) + var(--space-xxs)) - var(--v-timeline-marker-size)); 129 | transform: translateX(100%) translateY(-50%); 130 | } 131 | } 132 | 133 | &:nth-child(even) { 134 | margin-left: auto; 135 | 136 | .v-timeline__item { 137 | &:first-child { 138 | border-top-left-radius: 0; 139 | } 140 | } 141 | 142 | .v-timeline__date { 143 | left: calc(-2 * (var(--v-timeline-triangle-size) + var(--space-xxs)) - var(--v-timeline-marker-size)); 144 | transform: translateX(-100%) translateY(-50%); 145 | } 146 | } 147 | } 148 | 149 | .v-timeline__section--is-hidden { 150 | opacity: 0; // used in JS to hide section before the animation 151 | } 152 | 153 | .v-timeline__date { 154 | position: absolute; 155 | top: 0; 156 | white-space: nowrap; 157 | } 158 | 159 | // animations 160 | .js { 161 | .v-timeline[data-animation="on"] { 162 | .v-timeline__marker { 163 | opacity: 0; 164 | transform: scale(0.5); 165 | transition: transform .6s var(--ease-out), opacity .6s; 166 | } 167 | 168 | .v-timeline__item { 169 | opacity: 0; 170 | transition: transform .6s var(--ease-out), opacity .6s; 171 | } 172 | 173 | .v-timeline__section { 174 | &:nth-child(odd) .v-timeline__item { 175 | transform: translateX(-50px); 176 | } 177 | 178 | &:nth-child(even) .v-timeline__item { 179 | transform: translateX(50px); 180 | } 181 | } 182 | 183 | .v-timeline__section--animate { 184 | .v-timeline__item { 185 | transform: translateX(0) !important; 186 | opacity: 1; 187 | } 188 | 189 | .v-timeline__marker { 190 | transform: scale(1); 191 | opacity: 1; 192 | } 193 | } 194 | } 195 | } 196 | } 197 | 198 | // --icons 199 | .v-timeline--icons { 200 | --v-timeline-marker-size: 3em; 201 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_2_contact.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | @use '_1_google-maps.scss' as *; 3 | @use '_1_details-list.scss' as *; 4 | 5 | /* -------------------------------- 6 | 7 | File#: _2_contact 8 | Title: Contact 9 | Descr: Contact block w/ info about how to get in touch 10 | Usage: codyhouse.co/license 11 | 12 | -------------------------------- */ 13 | 14 | @include breakpoint(md) { 15 | .contact .google-maps { 16 | height: auto; 17 | padding-bottom: 0; 18 | } 19 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_2_device-group.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | @use '_1_devices.scss' as *; 3 | 4 | /* -------------------------------- 5 | 6 | File#: _2_device-group 7 | Title: Device Group 8 | Descr: A group of devices 9 | Usage: codyhouse.co/license 10 | 11 | -------------------------------- */ 12 | 13 | // 3 phones 14 | .device-group-1 { 15 | position: relative; 16 | z-index: 1; 17 | display: grid; 18 | align-items: center; 19 | grid-template-columns: repeat(10, 1fr); 20 | 21 | > * { 22 | position: relative; 23 | grid-row: 1 / -1; 24 | } 25 | 26 | > *:nth-child(1), > *:nth-child(3) { 27 | z-index: 1; 28 | } 29 | 30 | > *:nth-child(1) { 31 | grid-column: 1 / 5; 32 | } 33 | 34 | > *:nth-child(2) { 35 | z-index: 2; 36 | grid-column: 4 / 8; 37 | } 38 | 39 | > *:nth-child(3) { 40 | grid-column: 7 / 11; 41 | } 42 | 43 | .dev-phone-3d-wrapper { 44 | perspective: 1000px; 45 | } 46 | 47 | .dev-phone-3d-wrapper:first-child .dev-phone, 48 | .dev-phone-3d-wrapper:last-child .dev-phone { 49 | transition: transform .5s; 50 | } 51 | 52 | .dev-phone-3d-wrapper:first-child .dev-phone { 53 | transform: rotateY(30deg); 54 | transform-origin: left center; 55 | } 56 | 57 | .dev-phone-3d-wrapper:last-child .dev-phone { 58 | transform: rotateY(-30deg); 59 | transform-origin: right center; 60 | } 61 | 62 | &:hover { 63 | .dev-phone-3d-wrapper:first-child .dev-phone { 64 | transform: rotateY(20deg); 65 | } 66 | 67 | .dev-phone-3d-wrapper:last-child .dev-phone { 68 | transform: rotateY(-20deg); 69 | } 70 | } 71 | } 72 | 73 | // phone + laptop 74 | .device-group-2 { 75 | position: relative; 76 | z-index: 1; 77 | display: grid; 78 | align-items: end; 79 | grid-template-columns: repeat(12, 1fr); 80 | padding-bottom: 2.5%; 81 | 82 | > * { 83 | position: relative; 84 | grid-row: 1 / -1; 85 | } 86 | 87 | .dev-phone { 88 | z-index: 2; 89 | grid-column: 1 / 4; 90 | bottom: -5%; 91 | } 92 | 93 | .dev-laptop { 94 | z-index: 1; 95 | grid-column: 2 / 13; 96 | } 97 | } 98 | 99 | // phone + desktop 100 | .device-group-3 { 101 | position: relative; 102 | z-index: 1; 103 | display: grid; 104 | align-items: end; 105 | grid-template-columns: repeat(12, 1fr); 106 | padding-bottom: 3.75%; 107 | 108 | > * { 109 | position: relative; 110 | grid-row: 1 / -1; 111 | } 112 | 113 | .dev-phone { 114 | z-index: 2; 115 | grid-column: 1 / 4; 116 | bottom: -5%; 117 | } 118 | 119 | .dev-desktop { 120 | z-index: 1; 121 | grid-column: 2 / 13; 122 | } 123 | } 124 | 125 | // phone + desktop + laptop 126 | .device-group-4 { 127 | position: relative; 128 | z-index: 1; 129 | display: grid; 130 | align-items: end; 131 | grid-template-columns: repeat(12, 1fr); 132 | padding-bottom: 2.75%; 133 | 134 | > * { 135 | position: relative; 136 | grid-row: 1 / -1; 137 | } 138 | 139 | .dev-phone { 140 | z-index: 2; 141 | grid-column: 1 / 3; 142 | bottom: -5%; 143 | } 144 | 145 | .dev-desktop { 146 | z-index: 1; 147 | grid-column: 2 / 10; 148 | } 149 | 150 | .dev-laptop { 151 | z-index: 2; 152 | bottom: -5%; 153 | grid-column: 6 / 13; 154 | } 155 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_2_flexi-header.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | @use '_1_anim-menu-btn.scss' as *; 3 | @use '_1_search-input.scss' as *; 4 | 5 | /* -------------------------------- 6 | 7 | File#: _2_flexi-header 8 | Title: Flexi Header 9 | Descr: Customizable header template 10 | Usage: codyhouse.co/license 11 | 12 | -------------------------------- */ 13 | 14 | :root { 15 | --f-header-height: 50px; 16 | --f-header-logo-width: 104px; 17 | 18 | @include breakpoint(md) { 19 | --f-header-height: 70px; 20 | } 21 | } 22 | 23 | .f-header { 24 | height: var(--f-header-height); 25 | width: 100%; 26 | z-index: var(--z-index-header, 3); 27 | 28 | &::before { /* used in JS to detect menu style */ 29 | display: none; 30 | content: 'mobile'; 31 | } 32 | } 33 | 34 | .f-header--expanded { 35 | /* class added when navigation is visible - small devices only */ 36 | } 37 | 38 | .f-header__mobile-content { /* logo + menu button on small devices */ 39 | position: relative; 40 | display: flex; 41 | height: 100%; 42 | justify-content: space-between; 43 | align-items: center; 44 | z-index: 2; 45 | } 46 | 47 | .f-header__logo { 48 | display: block; 49 | width: var(--f-header-logo-width); 50 | flex-shrink: 0; 51 | text-decoration: none; 52 | 53 | svg, img { 54 | display: block; 55 | } 56 | } 57 | 58 | .f-header__nav-control { /* menu button */ 59 | --anim-menu-btn-size: 40px; 60 | /* 🍔 icon */ 61 | --anim-menu-btn-icon-size: 28px; 62 | --anim-menu-btn-icon-stroke: 2px; 63 | } 64 | 65 | .f-header__nav { 66 | position: absolute; 67 | top: 0; 68 | left: 0; 69 | width: 100%; 70 | max-height: calc(100vh - var(--f-header-offset, 0px)); 71 | overflow: auto; 72 | -webkit-overflow-scrolling: touch; 73 | overscroll-behavior: contain; 74 | padding: 0 0 var(--space-md); 75 | background-color: var(--color-bg); 76 | box-shadow: var(--shadow-md); 77 | z-index: 1; 78 | 79 | visibility: hidden; 80 | opacity: 0; 81 | transform: translateY(-1em); 82 | 83 | &::before { /* top header bg + border */ 84 | content: ''; 85 | display: block; 86 | position: sticky; 87 | top: 0; 88 | height: var(--f-header-height); 89 | background-color: inherit; 90 | border-bottom: 1px solid var(--color-contrast-lower); 91 | } 92 | } 93 | 94 | .f-header__nav--is-visible { 95 | visibility: visible; 96 | opacity: 1; 97 | transform: translateY(0); 98 | transition: visibility 0s, opacity .3s, transform .3s; 99 | } 100 | 101 | .f-header__nav-logo-wrapper { 102 | display: none; /* hide logo nav on small devices */ 103 | } 104 | 105 | .f-header__item { 106 | flex-shrink: 0; 107 | border-bottom: 1px solid var(--color-contrast-lower); 108 | } 109 | 110 | .f-header__dropdown-icon { 111 | --size: 16px; 112 | flex-shrink: 0; 113 | margin: 0 10px 0 auto; 114 | display: none; /* hide on mobile if link */ 115 | 116 | .f-header__dropdown-control & { 117 | display: block; 118 | } 119 | } 120 | 121 | .f-header__link, 122 | .f-header__dropdown-control, 123 | .f-header__dropdown-link, 124 | .f-header__btn, 125 | .f-header__form-control { 126 | font-size: var(--text-md); 127 | } 128 | 129 | .f-header__link, 130 | .f-header__dropdown-control, 131 | .f-header__dropdown-link { 132 | display: flex; 133 | align-items: center; 134 | color: var(--color-contrast-high); 135 | text-decoration: none; 136 | padding: var(--space-xs) 0; 137 | transition: .2s; 138 | 139 | &:hover, 140 | &[aria-current="page"] { 141 | opacity: 0.7; 142 | } 143 | } 144 | 145 | .f-header__btn, 146 | .f-header__form-control { 147 | width: 100%; 148 | margin: var(--space-xs) 0; 149 | } 150 | 151 | .f-header__dropdown-control { 152 | width: 100%; 153 | } 154 | 155 | .f-header__dropdown { /* sub navigation */ 156 | padding-left: var(--space-md); /* offset sub nav */ 157 | } 158 | 159 | .f-header__dropdown-control { 160 | + .f-header__dropdown { 161 | display: none; 162 | } 163 | 164 | &[aria-expanded="true"] + .f-header__dropdown { 165 | display: block; 166 | } 167 | } 168 | 169 | @include breakpoint(md) { 170 | .f-header::before { 171 | content: 'desktop'; 172 | } 173 | 174 | .f-header__mobile-content { 175 | display: none; /* hide logo + menu (mobile content) */ 176 | } 177 | 178 | .f-header__nav { 179 | /* reset */ 180 | position: static; 181 | padding: 0; 182 | background-color: transparent; 183 | box-shadow: none; 184 | visibility: visible; 185 | opacity: 1; 186 | transform: translateY(0); 187 | transition: none; 188 | max-height: none; 189 | overflow: visible; 190 | overscroll-behavior: auto; 191 | height: var(--f-header-height); 192 | 193 | &::before { /* reset */ 194 | display: none; 195 | } 196 | } 197 | 198 | .f-header__nav-logo-wrapper { 199 | display: flex; 200 | } 201 | 202 | .f-header__nav-grid, 203 | .f-header__list { 204 | display: flex; 205 | align-items: center; 206 | } 207 | 208 | .f-header__nav-grid { 209 | height: 100%; 210 | } 211 | 212 | .f-header__item { 213 | position: relative; 214 | border-bottom: none; 215 | margin-right: var(--space-xs); /* margin between nav items */ 216 | 217 | &:last-child { 218 | margin-right: 0; 219 | } 220 | } 221 | 222 | .f-header__dropdown-icon { 223 | --size: 12px; 224 | display: block; 225 | margin: 0 0 0 var(--space-xxxxs); 226 | } 227 | 228 | .f-header__link, 229 | .f-header__dropdown-control, 230 | .f-header__dropdown-link, 231 | .f-header__btn, 232 | .f-header__form-control { 233 | font-size: 1.125rem; 234 | } 235 | 236 | .f-header__link { 237 | padding: var(--space-xxxs) var(--space-xxs); 238 | } 239 | 240 | .f-header__link--icon { 241 | span { 242 | display: none; /* hide icon label */ 243 | } 244 | } 245 | 246 | .f-header__btn, 247 | .f-header__form-control { 248 | margin: 0; /* reset */ 249 | } 250 | 251 | .f-header__dropdown { 252 | position: absolute; 253 | top: 100%; 254 | width: 220px; 255 | left: calc(50% - 110px); 256 | padding: var(--space-xxxs) 0; 257 | background-color: var(--color-bg-light); 258 | border-radius: var(--radius-md); 259 | box-shadow: var(--inner-glow), var(--shadow-md); 260 | z-index: var(--z-index-popover, 5); 261 | 262 | /* hide */ 263 | visibility: hidden; 264 | opacity: 0; 265 | transition: visibility 0s .2s, opacity .2s 0s; 266 | 267 | .f-header__dropdown-control + & { 268 | display: block; /* reset style */ 269 | } 270 | 271 | .f-header__item:hover &, 272 | .f-header__dropdown-control[aria-expanded="true"] + & { 273 | visibility: visible; 274 | opacity: 1; 275 | transition: visibility .2s 0s, opacity .2s 0s; 276 | } 277 | } 278 | 279 | .f-header__dropdown-link { 280 | color: var(--color-contrast-high); 281 | padding: var(--space-xs) var(--space-sm); 282 | transition: .2s; 283 | 284 | &:hover { 285 | background-color: alpha(var(--color-contrast-higher), 0.075); 286 | color: var(--color-contrast-higher); 287 | } 288 | } 289 | } 290 | 291 | html:not(.js) { 292 | .f-header { 293 | height: auto; 294 | } 295 | 296 | .f-header__nav-control { 297 | display: none; 298 | } 299 | 300 | .f-header__nav { 301 | position: static; 302 | padding: var(--space-xxs) 0 var(--space-md); 303 | box-shadow: none; 304 | visibility: visible; 305 | opacity: 1; 306 | transform: translateY(0); 307 | } 308 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_2_image-interest-points.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | @use '_1_modal-window.scss' as *; 3 | 4 | /* -------------------------------- 5 | 6 | File#: _2_points-of-interest 7 | Title: Points Of Interest 8 | Descr: Highlight the points of interest of an image and provide additional details for each one. 9 | Usage: codyhouse.co/license 10 | 11 | -------------------------------- */ 12 | 13 | .poi { 14 | pointer-events: none; 15 | } 16 | 17 | .poi__item { 18 | position: absolute; 19 | pointer-events: auto; 20 | } 21 | 22 | .poi__btn { 23 | display: flex; 24 | align-items: center; 25 | justify-content: center; 26 | 27 | --size: 32px; 28 | height: var(--size); 29 | width: var(--size); 30 | border-radius: 50%; 31 | background-color: var(--color-accent); 32 | box-shadow: var(--inner-glow-top), var(--shadow-sm); 33 | 34 | cursor: pointer; 35 | 36 | transition: .2s; 37 | 38 | &::after { /* pulse ring */ 39 | content: ''; 40 | position: absolute; 41 | width: 100%; 42 | height: 100%; 43 | top: 0; 44 | left: 0; 45 | border-radius: inherit; 46 | pointer-events: none; 47 | box-shadow: inset 0 0 1px 1px var(--color-accent); 48 | animation: poi-pulse 2s infinite; 49 | } 50 | 51 | .icon { 52 | color: var(--color-white); /* icon color */ 53 | --size: 12px; 54 | transition: transform .3s var(--ease-out-back); 55 | } 56 | 57 | &:hover .icon { 58 | transform: scale(1.1); 59 | } 60 | } 61 | 62 | .poi__item--visited button { /* style of clicked button */ 63 | background-color: alpha(var(--color-black), 0.95); 64 | backdrop-filter: blur(10px); 65 | 66 | &::after { 67 | display: none; 68 | } 69 | } 70 | 71 | @keyframes poi-pulse { 72 | 0% { 73 | transform: scale(1); 74 | opacity: 1; 75 | } 76 | 77 | 50% { 78 | opacity: 1; 79 | } 80 | 81 | 100% { 82 | transform: scale(1.6); 83 | opacity: 0; 84 | } 85 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_2_pricing-table.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | @use '_1_radio-switch.scss' as *; 3 | 4 | /* -------------------------------- 5 | 6 | File#: _2_pricing-table 7 | Title: Pricing Table 8 | Descr: A table used to compare prices and features of different products 9 | Usage: codyhouse.co/license 10 | 11 | -------------------------------- */ 12 | 13 | .p-table__item { 14 | background-color: var(--color-bg-dark); 15 | border-radius: var(--radius-lg); 16 | box-shadow: var(--inner-glow); 17 | padding: var(--space-md); 18 | display: flex; 19 | flex-direction: column; 20 | } 21 | 22 | .p-table__item--popular { 23 | background-color: var(--color-bg-light); 24 | box-shadow: 0 0 0 2px var(--color-primary), var(--shadow-md); 25 | } 26 | 27 | .p-table__badge { 28 | font-size: var(--text-sm); 29 | background-color: var(--color-contrast-high); 30 | color: var(--color-bg); 31 | padding: var(--space-xxxs) var(--space-xxs); 32 | @include fontSmooth; 33 | vertical-align: middle; 34 | border-radius: var(--radius-md); 35 | } 36 | 37 | .p-table__price { 38 | span { // amount 39 | font-size: var(--text-xxxl); 40 | font-weight: bold; 41 | } 42 | 43 | i { // month/year 44 | color: var(--color-contrast-low); 45 | } 46 | } 47 | 48 | .p-table__features { 49 | li { 50 | margin-bottom: var(--space-xs); 51 | } 52 | } 53 | 54 | // --has-switch 55 | .p-table__switch { 56 | display: none; 57 | } 58 | 59 | .js { 60 | .p-table--has-switch { 61 | .p-table__price-wrapper { 62 | position: relative; 63 | overflow: hidden; 64 | } 65 | 66 | .p-table__price { 67 | will-change: transform; 68 | transition: transform 0.3s, opacity 0.3s; 69 | transition-timing-function: var(--ease-out); 70 | 71 | &[data-transition-delay="2nd"] { 72 | transition-delay: 0.1s; 73 | } 74 | 75 | &[data-transition-delay="3rd"] { 76 | transition-delay: 0.2s; 77 | } 78 | } 79 | 80 | .p-table__price--month { 81 | position: absolute; 82 | top: 0; 83 | left: 0; 84 | width: 100%; 85 | } 86 | 87 | .p-table__price--year { 88 | pointer-events: none; 89 | opacity: 0; 90 | transform: translateY(100%); 91 | } 92 | } 93 | 94 | .p-table--yearly { 95 | .p-table__price--month { 96 | pointer-events: none; 97 | opacity: 0; 98 | transform: translateY(-100%); 99 | } 100 | 101 | .p-table__price--year { 102 | pointer-events: auto; 103 | opacity: 1; 104 | transform: translateY(0); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_2_sticky-sharebar.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | @use '_1_social-sharing.scss' as *; 3 | 4 | /* -------------------------------- 5 | 6 | File#: _2_sticky-sharebar 7 | Title: Sticky Sharebar 8 | Descr: Sticky social sharing bar 9 | Usage: codyhouse.co/license 10 | 11 | -------------------------------- */ 12 | 13 | .sticky-sharebar { 14 | display: flex; 15 | align-items: center; 16 | position: fixed; 17 | height: 100%; 18 | top: 0; 19 | right: var(--space-md); 20 | pointer-events: none; 21 | z-index: var(--z-index-fixed-element, 10); 22 | 23 | transition: visibility 0s .3s, opacity .3s, transform .3s var(--ease-in-out); 24 | transform: translateX(10%); 25 | opacity: 0; 26 | visibility: hidden; 27 | } 28 | 29 | 30 | .sticky-sharebar--on-target { 31 | transition: visibility 0s, opacity .3s, transform .3s var(--ease-in-out); 32 | transform: translateX(0); 33 | opacity: 1; 34 | visibility: visible; 35 | } 36 | 37 | .sticky-sharebar__list { 38 | pointer-events: auto; 39 | background-color: alpha(var(--color-bg-light), 0.95); 40 | backdrop-filter: blur(5px); 41 | border-radius: 50em; 42 | box-shadow: var(--inner-glow), var(--shadow-md); 43 | padding: 4px; 44 | } 45 | 46 | .sticky-sharebar__btn { 47 | --size: 2.2em; 48 | width: var(--size); 49 | height: var(--size); 50 | 51 | position: relative; 52 | display: flex; 53 | border-radius: 50%; 54 | 55 | .icon { 56 | position: relative; 57 | color: var(--color-contrast-medium); /* icon color */ 58 | display: block; 59 | margin: auto; 60 | z-index: 2; 61 | transition: color .2s; 62 | } 63 | 64 | &::before { /* animated bg */ 65 | content: ''; 66 | position: absolute; 67 | top: 0; 68 | left: 0; 69 | width: 100%; 70 | height: 100%; 71 | z-index: 1; 72 | border-radius: inherit; 73 | background-color: alpha(var(--color-contrast-higher), 0.1); 74 | transform: scale(0); 75 | transition: transform .2s var(--ease-out); 76 | } 77 | 78 | &:hover { 79 | .icon { 80 | color: var(--color-contrast-higher); 81 | } 82 | 83 | &::before { 84 | transform: scale(1); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/components/_3_feature-v14.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | @use '_1_devices.scss' as *; 3 | @use '_2_device-group.scss' as *; 4 | 5 | /* -------------------------------- 6 | 7 | File#: _3_feature-v14 8 | Title: Feature v14 9 | Descr: Feature content with tech devices 10 | Usage: codyhouse.co/license 11 | 12 | -------------------------------- */ -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/custom-style/_buttons.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | // -------------------------------- 4 | 5 | // (START) Global editor code https://codyhouse.co/ds/globals/buttons 6 | 7 | // -------------------------------- 8 | 9 | :root { 10 | --btn-font-size: 1em; 11 | --btn-padding-x: var(--space-sm); 12 | --btn-padding-y: var(--space-xxs); 13 | --btn-radius: var(--radius-md); 14 | } 15 | 16 | .btn { 17 | background: var(--color-bg-dark); 18 | color: var(--color-contrast-higher); 19 | cursor: pointer; 20 | text-decoration: none; 21 | line-height: 1.2; 22 | @include fontSmooth; 23 | transition: all 0.2s ease; 24 | will-change: transform; 25 | 26 | &:focus { 27 | box-shadow: 0px 0px 0px 2px alpha(var(--color-contrast-higher), 0.15); 28 | outline: none; 29 | } 30 | 31 | &:active { 32 | transform: translateY(2px); 33 | } 34 | } 35 | 36 | // themes 37 | .btn--primary { 38 | background: var(--color-primary); 39 | color: var(--color-white); 40 | box-shadow: inset 0px 1px 0px alpha(var(--color-white), 0.15), var(--shadow-xs); 41 | 42 | &:hover { 43 | background: var(--color-primary-light); 44 | box-shadow: inset 0px 1px 0px alpha(var(--color-white), 0.15), var(--shadow-sm); 45 | } 46 | 47 | &:focus { 48 | box-shadow: inset 0px 1px 0px alpha(var(--color-white), 0.15), 0px 0px 0px 2px alpha(var(--color-primary), 0.2); 49 | } 50 | } 51 | 52 | .btn--subtle { 53 | background: var(--color-bg-light); 54 | color: var(--color-contrast-higher); 55 | box-shadow: inset 0px 0px 0px 1px var(--color-contrast-lower), var(--shadow-xs); 56 | 57 | &:hover { 58 | background: var(--color-bg-lighter); 59 | box-shadow: inset 0px 0px 0px 1px var(--color-contrast-lower), var(--shadow-sm); 60 | } 61 | 62 | &:focus { 63 | box-shadow: inset 0px 0px 0px 1px var(--color-contrast-lower), 0px 0px 0px 2px alpha(var(--color-contrast-higher), 0.05); 64 | } 65 | } 66 | 67 | .btn--accent { 68 | background: var(--color-accent); 69 | color: var(--color-white); 70 | box-shadow: inset 0px 1px 0px alpha(var(--color-white), 0.15), var(--shadow-xs); 71 | 72 | &:hover { 73 | background: var(--color-accent-light); 74 | box-shadow: inset 0px 1px 0px alpha(var(--color-white), 0.15), var(--shadow-sm); 75 | } 76 | 77 | &:focus { 78 | box-shadow: inset 0px 1px 0px alpha(var(--color-white), 0.15), 0px 0px 0px 2px alpha(var(--color-accent), 0.2); 79 | } 80 | } 81 | 82 | .btn--dark { 83 | background-color: var(--color-black); 84 | color: var(--color-white); 85 | } 86 | 87 | .btn--light { 88 | background-color: var(--color-white); 89 | color: var(--color-black); 90 | } 91 | 92 | // feedback 93 | .btn--disabled, .btn[disabled], .btn[readonly] { 94 | opacity: 0.6; 95 | cursor: not-allowed; 96 | } 97 | 98 | // size 99 | .btn--sm { 100 | font-size: 0.8em; 101 | } 102 | 103 | .btn--md { 104 | font-size: 1.2em; 105 | } 106 | 107 | .btn--lg { 108 | font-size: 1.4em; 109 | } 110 | 111 | // -------------------------------- 112 | 113 | // (END) Global editor code 114 | 115 | // -------------------------------- -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/custom-style/_colors.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | // -------------------------------- 4 | 5 | // (START) Global editor code https://codyhouse.co/ds/globals/colors 6 | 7 | // -------------------------------- 8 | 9 | :root, [data-theme="default"] { 10 | // main 11 | @include defineColorHSL(--color-primary-darker, 237, 68%, 29%); 12 | @include defineColorHSL(--color-primary-dark, 237, 68%, 38%); 13 | @include defineColorHSL(--color-primary, 237, 68%, 47%); 14 | @include defineColorHSL(--color-primary-light, 237, 68%, 55%); 15 | @include defineColorHSL(--color-primary-lighter, 237, 68%, 61%); 16 | 17 | @include defineColorHSL(--color-accent-darker, 7, 86%, 50%); 18 | @include defineColorHSL(--color-accent-dark, 7, 88%, 58%); 19 | @include defineColorHSL(--color-accent, 7, 98%, 65%); 20 | @include defineColorHSL(--color-accent-light, 7, 98%, 71%); 21 | @include defineColorHSL(--color-accent-lighter, 7, 98%, 77%); 22 | 23 | @include defineColorHSL(--color-black, 204, 28%, 7%); 24 | @include defineColorHSL(--color-white, 0, 0%, 100%); 25 | 26 | // feedback 27 | @include defineColorHSL(--color-warning-darker, 46, 100%, 47%); 28 | @include defineColorHSL(--color-warning-dark, 46, 100%, 50%); 29 | @include defineColorHSL(--color-warning, 46, 100%, 61%); 30 | @include defineColorHSL(--color-warning-light, 46, 100%, 71%); 31 | @include defineColorHSL(--color-warning-lighter, 46, 100%, 80%); 32 | 33 | @include defineColorHSL(--color-success-darker, 122, 50%, 47%); 34 | @include defineColorHSL(--color-success-dark, 122, 50%, 52%); 35 | @include defineColorHSL(--color-success, 122, 50%, 60%); 36 | @include defineColorHSL(--color-success-light, 122, 50%, 69%); 37 | @include defineColorHSL(--color-success-lighter, 122, 50%, 76%); 38 | 39 | @include defineColorHSL(--color-error-darker, 342, 89%, 38%); 40 | @include defineColorHSL(--color-error-dark, 342, 89%, 43%); 41 | @include defineColorHSL(--color-error, 342, 89%, 48%); 42 | @include defineColorHSL(--color-error-light, 342, 89%, 56%); 43 | @include defineColorHSL(--color-error-lighter, 342, 89%, 62%); 44 | 45 | // background 46 | @include defineColorHSL(--color-bg-darker, 210, 4%, 89%); 47 | @include defineColorHSL(--color-bg-dark, 180, 3%, 94%); 48 | @include defineColorHSL(--color-bg, 0, 0%, 100%); 49 | @include defineColorHSL(--color-bg-light, 180, 3%, 100%); 50 | @include defineColorHSL(--color-bg-lighter, 210, 4%, 100%); 51 | 52 | // color contrasts 53 | @include defineColorHSL(--color-contrast-lower, 180, 1%, 84%); 54 | @include defineColorHSL(--color-contrast-low, 210, 2%, 64%); 55 | @include defineColorHSL(--color-contrast-medium, 204, 2%, 46%); 56 | @include defineColorHSL(--color-contrast-high, 210, 7%, 21%); 57 | @include defineColorHSL(--color-contrast-higher, 204, 28%, 7%); 58 | } 59 | 60 | @supports(--css: variables) { 61 | [data-theme="dark"] { 62 | // main 63 | @include defineColorHSL(--color-primary-darker, 237, 96%, 45%); 64 | @include defineColorHSL(--color-primary-dark, 237, 96%, 54%); 65 | @include defineColorHSL(--color-primary, 237, 96%, 62%); 66 | @include defineColorHSL(--color-primary-light, 237, 96%, 67%); 67 | @include defineColorHSL(--color-primary-lighter, 237, 96%, 72%); 68 | 69 | @include defineColorHSL(--color-accent-darker, 7, 86%, 50%); 70 | @include defineColorHSL(--color-accent-dark, 7, 88%, 58%); 71 | @include defineColorHSL(--color-accent, 7, 98%, 65%); 72 | @include defineColorHSL(--color-accent-light, 7, 98%, 71%); 73 | @include defineColorHSL(--color-accent-lighter, 7, 98%, 77%); 74 | 75 | @include defineColorHSL(--color-black, 204, 28%, 7%); 76 | @include defineColorHSL(--color-white, 0, 0%, 100%); 77 | 78 | // feedback 79 | @include defineColorHSL(--color-warning-darker, 46, 100%, 47%); 80 | @include defineColorHSL(--color-warning-dark, 46, 100%, 50%); 81 | @include defineColorHSL(--color-warning, 46, 100%, 61%); 82 | @include defineColorHSL(--color-warning-light, 46, 100%, 71%); 83 | @include defineColorHSL(--color-warning-lighter, 46, 100%, 80%); 84 | 85 | @include defineColorHSL(--color-success-darker, 122, 50%, 47%); 86 | @include defineColorHSL(--color-success-dark, 122, 50%, 52%); 87 | @include defineColorHSL(--color-success, 122, 50%, 60%); 88 | @include defineColorHSL(--color-success-light, 122, 50%, 69%); 89 | @include defineColorHSL(--color-success-lighter, 122, 50%, 76%); 90 | 91 | @include defineColorHSL(--color-error-darker, 342, 92%, 41%); 92 | @include defineColorHSL(--color-error-dark, 342, 92%, 47%); 93 | @include defineColorHSL(--color-error, 342, 92%, 54%); 94 | @include defineColorHSL(--color-error-light, 342, 92%, 60%); 95 | @include defineColorHSL(--color-error-lighter, 342, 92%, 65%); 96 | 97 | // background 98 | @include defineColorHSL(--color-bg-darker, 204, 15%, 6%); 99 | @include defineColorHSL(--color-bg-dark, 203, 18%, 9%); 100 | @include defineColorHSL(--color-bg, 203, 24%, 13%); 101 | @include defineColorHSL(--color-bg-light, 203, 18%, 17%); 102 | @include defineColorHSL(--color-bg-lighter, 204, 15%, 20%); 103 | 104 | // color contrasts 105 | @include defineColorHSL(--color-contrast-lower, 208, 12%, 24%); 106 | @include defineColorHSL(--color-contrast-low, 208, 6%, 40%); 107 | @include defineColorHSL(--color-contrast-medium, 213, 5%, 56%); 108 | @include defineColorHSL(--color-contrast-high, 223, 8%, 82%); 109 | @include defineColorHSL(--color-contrast-higher, 240, 100%, 99%); 110 | 111 | // font rendering 112 | -webkit-font-smoothing: antialiased; 113 | -moz-osx-font-smoothing: grayscale; 114 | } 115 | } 116 | 117 | @supports(--css: variables) { 118 | [data-theme="soft"] { 119 | // main 120 | @include defineColorHSL(--color-primary-darker, 237, 68%, 29%); 121 | @include defineColorHSL(--color-primary-dark, 237, 68%, 38%); 122 | @include defineColorHSL(--color-primary, 237, 68%, 47%); 123 | @include defineColorHSL(--color-primary-light, 237, 68%, 55%); 124 | @include defineColorHSL(--color-primary-lighter, 237, 68%, 61%); 125 | 126 | @include defineColorHSL(--color-accent-darker, 7, 86%, 50%); 127 | @include defineColorHSL(--color-accent-dark, 7, 88%, 58%); 128 | @include defineColorHSL(--color-accent, 7, 98%, 65%); 129 | @include defineColorHSL(--color-accent-light, 7, 98%, 71%); 130 | @include defineColorHSL(--color-accent-lighter, 7, 98%, 77%); 131 | 132 | @include defineColorHSL(--color-black, 204, 28%, 7%); 133 | @include defineColorHSL(--color-white, 0, 0%, 100%); 134 | 135 | // feedback 136 | @include defineColorHSL(--color-warning-darker, 46, 100%, 47%); 137 | @include defineColorHSL(--color-warning-dark, 46, 100%, 50%); 138 | @include defineColorHSL(--color-warning, 46, 100%, 61%); 139 | @include defineColorHSL(--color-warning-light, 46, 100%, 71%); 140 | @include defineColorHSL(--color-warning-lighter, 46, 100%, 80%); 141 | 142 | @include defineColorHSL(--color-success-darker, 122, 50%, 47%); 143 | @include defineColorHSL(--color-success-dark, 122, 50%, 52%); 144 | @include defineColorHSL(--color-success, 122, 50%, 60%); 145 | @include defineColorHSL(--color-success-light, 122, 50%, 69%); 146 | @include defineColorHSL(--color-success-lighter, 122, 50%, 76%); 147 | 148 | @include defineColorHSL(--color-error-darker, 342, 89%, 38%); 149 | @include defineColorHSL(--color-error-dark, 342, 89%, 43%); 150 | @include defineColorHSL(--color-error, 342, 89%, 48%); 151 | @include defineColorHSL(--color-error-light, 342, 89%, 56%); 152 | @include defineColorHSL(--color-error-lighter, 342, 89%, 62%); 153 | 154 | // background 155 | @include defineColorHSL(--color-bg-darker, 248, 27%, 76%); 156 | @include defineColorHSL(--color-bg-dark, 249, 32%, 80%); 157 | @include defineColorHSL(--color-bg, 250, 47%, 85%); 158 | @include defineColorHSL(--color-bg-light, 249, 39%, 87%); 159 | @include defineColorHSL(--color-bg-lighter, 249, 32%, 90%); 160 | 161 | // color contrasts 162 | @include defineColorHSL(--color-contrast-lower, 248, 21%, 72%); 163 | @include defineColorHSL(--color-contrast-low, 243, 10%, 55%); 164 | @include defineColorHSL(--color-contrast-medium, 240, 8%, 40%); 165 | @include defineColorHSL(--color-contrast-high, 220, 12%, 19%); 166 | @include defineColorHSL(--color-contrast-higher, 204, 28%, 7%); 167 | } 168 | } 169 | 170 | @supports(--css: variables) { 171 | [data-theme="secondary"] { 172 | // main 173 | @include defineColorHSL(--color-primary-darker, 237, 86%, 9%); 174 | @include defineColorHSL(--color-primary-dark, 237, 86%, 14%); 175 | @include defineColorHSL(--color-primary, 237, 86%, 19%); 176 | @include defineColorHSL(--color-primary-light, 237, 86%, 28%); 177 | @include defineColorHSL(--color-primary-lighter, 237, 86%, 36%); 178 | 179 | @include defineColorHSL(--color-accent-darker, 7, 86%, 50%); 180 | @include defineColorHSL(--color-accent-dark, 7, 88%, 58%); 181 | @include defineColorHSL(--color-accent, 7, 98%, 65%); 182 | @include defineColorHSL(--color-accent-light, 7, 98%, 71%); 183 | @include defineColorHSL(--color-accent-lighter, 7, 98%, 77%); 184 | 185 | @include defineColorHSL(--color-black, 204, 28%, 7%); 186 | @include defineColorHSL(--color-white, 0, 0%, 100%); 187 | 188 | // feedback 189 | @include defineColorHSL(--color-warning-darker, 46, 100%, 47%); 190 | @include defineColorHSL(--color-warning-dark, 46, 100%, 50%); 191 | @include defineColorHSL(--color-warning, 46, 100%, 61%); 192 | @include defineColorHSL(--color-warning-light, 46, 100%, 71%); 193 | @include defineColorHSL(--color-warning-lighter, 46, 100%, 80%); 194 | 195 | @include defineColorHSL(--color-success-darker, 122, 50%, 47%); 196 | @include defineColorHSL(--color-success-dark, 122, 50%, 52%); 197 | @include defineColorHSL(--color-success, 122, 50%, 60%); 198 | @include defineColorHSL(--color-success-light, 122, 50%, 69%); 199 | @include defineColorHSL(--color-success-lighter, 122, 50%, 76%); 200 | 201 | @include defineColorHSL(--color-error-darker, 342, 89%, 38%); 202 | @include defineColorHSL(--color-error-dark, 342, 89%, 43%); 203 | @include defineColorHSL(--color-error, 342, 89%, 48%); 204 | @include defineColorHSL(--color-error-light, 342, 89%, 56%); 205 | @include defineColorHSL(--color-error-lighter, 342, 89%, 62%); 206 | 207 | // background 208 | @include defineColorHSL(--color-bg-darker, 84, 13%, 27%); 209 | @include defineColorHSL(--color-bg-dark, 87, 14%, 29%); 210 | @include defineColorHSL(--color-bg, 86, 17%, 33%); 211 | @include defineColorHSL(--color-bg-light, 87, 14%, 37%); 212 | @include defineColorHSL(--color-bg-lighter, 84, 13%, 39%); 213 | 214 | // color contrasts 215 | @include defineColorHSL(--color-contrast-lower, 86, 12%, 42%); 216 | @include defineColorHSL(--color-contrast-low, 84, 9%, 55%); 217 | @include defineColorHSL(--color-contrast-medium, 84, 9%, 68%); 218 | @include defineColorHSL(--color-contrast-high, 80, 9%, 87%); 219 | @include defineColorHSL(--color-contrast-higher, 0, 0%, 100%); 220 | 221 | // font rendering 222 | -webkit-font-smoothing: antialiased; 223 | -moz-osx-font-smoothing: grayscale; 224 | } 225 | } 226 | 227 | // -------------------------------- 228 | 229 | // (END) Global editor code 230 | 231 | // -------------------------------- -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/custom-style/_forms.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | // -------------------------------- 4 | 5 | // (START) Global editor code https://codyhouse.co/ds/globals/forms 6 | 7 | // -------------------------------- 8 | 9 | :root { 10 | --form-control-font-size: 1em; 11 | --form-control-padding-x: var(--space-xs); 12 | --form-control-padding-y: var(--space-xxs); 13 | --form-control-radius: var(--radius-md); 14 | } 15 | 16 | .form-control { 17 | background: var(--color-bg-dark); 18 | line-height: 1.2; 19 | box-shadow: inset 0px 0px 0px 1px var(--color-contrast-lower); 20 | transition: all 0.2s ease; 21 | 22 | &::placeholder { 23 | opacity: 1; 24 | color: var(--color-contrast-low); 25 | } 26 | 27 | &:focus { 28 | background: var(--color-bg); 29 | box-shadow: inset 0px 0px 0px 1px alpha(var(--color-contrast-lower), 0), 0px 0px 0px 2px var(--color-primary), var(--shadow-sm); 30 | outline: none; 31 | } 32 | } 33 | 34 | .form-control--disabled, .form-control[disabled], .form-control[readonly] { 35 | opacity: 0.5; 36 | cursor: not-allowed; 37 | } 38 | 39 | .form-control[aria-invalid="true"], .form-control.form-control--error { 40 | box-shadow: inset 0px 0px 0px 1px alpha(var(--color-contrast-lower), 0), 0px 0px 0px 2px var(--color-error); 41 | 42 | &:focus { 43 | box-shadow: inset 0px 0px 0px 1px alpha(var(--color-contrast-lower), 0), 0px 0px 0px 2px var(--color-error), var(--shadow-sm); 44 | } 45 | } 46 | 47 | .form-legend {} 48 | 49 | .form-label {} 50 | 51 | // -------------------------------- 52 | 53 | // (END) Global editor code 54 | 55 | // -------------------------------- -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/custom-style/_icons.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | :root { 4 | // size - 👇 uncomment to modify default icon sizes 5 | // --icon-xxxs: 8px; 6 | // --icon-xxs: 12px; 7 | // --icon-xs: 16px; 8 | // --icon-sm: 24px; 9 | // --icon-md: 32px; 10 | // --icon-lg: 48px; 11 | // --icon-xl: 64px; 12 | // --icon-xxl: 96px; 13 | // --icon-xxxl: 128px; 14 | } 15 | 16 | .icon { 17 | // 👇 include the font-family declaration here if you are using an icon font 18 | // font-family: 'fontName'; 19 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/custom-style/_shared-styles.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | :root { 4 | // radius 5 | --radius: 0.25em; // border radius base size 6 | // 👇 uncomment to modify default radius values 7 | // --radius-sm: calc(var(--radius)/2); 8 | // --radius-md: var(--radius); 9 | // --radius-lg: calc(var(--radius)*2); 10 | 11 | // box shadow - 👇 uncomment to modify default shadow values 12 | // --shadow-xs: 0 0.1px 0.3px rgba(0, 0, 0, 0.06), 13 | // 0 1px 2px rgba(0, 0, 0, 0.12); 14 | // --shadow-sm: 0 0.3px 0.4px rgba(0, 0, 0, 0.025), 15 | // 0 0.9px 1.5px rgba(0, 0, 0, 0.05), 16 | // 0 3.5px 6px rgba(0, 0, 0, 0.1); 17 | // --shadow-md: 0 0.9px 1.5px rgba(0, 0, 0, 0.03), 18 | // 0 3.1px 5.5px rgba(0, 0, 0, 0.08), 19 | // 0 14px 25px rgba(0, 0, 0, 0.12); 20 | // --shadow-lg: 0 1.2px 1.9px -1px rgba(0, 0, 0, 0.014), 21 | // 0 3.3px 5.3px -1px rgba(0, 0, 0, 0.038), 22 | // 0 8.5px 12.7px -1px rgba(0, 0, 0, 0.085), 23 | // 0 30px 42px -1px rgba(0, 0, 0, 0.15); 24 | // --shadow-xl: 0 1.5px 2.1px -6px rgba(0, 0, 0, 0.012), 25 | // 0 3.6px 5.2px -6px rgba(0, 0, 0, 0.035), 26 | // 0 7.3px 10.6px -6px rgba(0, 0, 0, 0.07), 27 | // 0 16.2px 21.9px -6px rgba(0, 0, 0, 0.117), 28 | // 0 46px 60px -6px rgba(0, 0, 0, 0.2); 29 | } 30 | 31 | // -------------------------------- 32 | 33 | // (START) Global editor code https://codyhouse.co/ds/globals/shared-styles 34 | 35 | // -------------------------------- 36 | 37 | .hover\:reduce-opacity { 38 | opacity: 1; 39 | transition: all 0.3s ease; 40 | 41 | &:hover { 42 | opacity: 0.8; 43 | } 44 | } 45 | 46 | .hover\:scale { 47 | transition: transform 0.3s var(--ease-out-back); 48 | 49 | &:hover { 50 | transform: scale(1.1); 51 | } 52 | } 53 | 54 | .hover\:elevate { 55 | box-shadow: var(--shadow-sm); 56 | transition: all 0.3s ease; 57 | 58 | &:hover { 59 | box-shadow: var(--shadow-md); 60 | } 61 | } 62 | 63 | // text styles 64 | .link-subtle { 65 | color: inherit; 66 | cursor: pointer; 67 | text-decoration: none; 68 | transition: all 0.2s ease; 69 | 70 | &:hover { 71 | color: var(--color-primary); 72 | } 73 | } 74 | 75 | // -------------------------------- 76 | 77 | // (END) Global editor code 78 | 79 | // -------------------------------- -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/custom-style/_spacing.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | // -------------------------------- 4 | 5 | // (START) Global editor code https://codyhouse.co/ds/globals/spacing 6 | 7 | // -------------------------------- 8 | 9 | // 👇 uncomment to modify default spacing scale 10 | // :root { 11 | // --space-unit: 1rem; 12 | // } 13 | 14 | // :root, * { 15 | // --space-xxxxs: calc(0.125 * var(--space-unit)); 16 | // --space-xxxs: calc(0.25 * var(--space-unit)); 17 | // --space-xxs: calc(0.375 * var(--space-unit)); 18 | // --space-xs: calc(0.5 * var(--space-unit)); 19 | // --space-sm: calc(0.75 * var(--space-unit)); 20 | // --space-md: calc(1.25 * var(--space-unit)); 21 | // --space-lg: calc(2 * var(--space-unit)); 22 | // --space-xl: calc(3.25 * var(--space-unit)); 23 | // --space-xxl: calc(5.25 * var(--space-unit)); 24 | // --space-xxxl: calc(8.5 * var(--space-unit)); 25 | // --space-xxxxl: calc(13.75 * var(--space-unit)); 26 | // --component-padding: var(--space-md); 27 | // } 28 | 29 | @include breakpoint(md) { 30 | :root, * { 31 | --space-xxxxs: calc(0.1875 * var(--space-unit)); 32 | --space-xxxs: calc(0.375 * var(--space-unit)); 33 | --space-xxs: calc(0.5625 * var(--space-unit)); 34 | --space-xs: calc(0.75 * var(--space-unit)); 35 | --space-sm: calc(1.125 * var(--space-unit)); 36 | --space-md: calc(2 * var(--space-unit)); 37 | --space-lg: calc(3.125 * var(--space-unit)); 38 | --space-xl: calc(5.125 * var(--space-unit)); 39 | --space-xxl: calc(8.25 * var(--space-unit)); 40 | --space-xxxl: calc(13.25 * var(--space-unit)); 41 | --space-xxxxl: calc(21.5 * var(--space-unit)); 42 | } 43 | } 44 | 45 | // -------------------------------- 46 | 47 | // (END) Global editor code 48 | 49 | // -------------------------------- -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/custom-style/_typography.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | // -------------------------------- 4 | 5 | // (START) Global editor code https://codyhouse.co/ds/globals/typography 6 | 7 | // -------------------------------- 8 | 9 | :root { 10 | // font family 11 | --font-primary: Inter, system-ui, sans-serif; 12 | --font-secondary: 'Playfair Display', serif; 13 | 14 | // font size 15 | --text-base-size: 1rem; // body font-size 16 | --text-scale-ratio: 1.2; // multiplier used to generate the type scale values 👇 17 | 18 | // line-height 19 | --body-line-height: 1.4; 20 | --heading-line-height: 1.2; 21 | 22 | // capital letters - used in combo with the lhCrop mixin 23 | --font-primary-capital-letter: 0.85; 24 | --font-secondary-capital-letter: 0.85; 25 | 26 | // unit - don't modify unless you want to change the typography unit (e.g., from Rem to Em units) 27 | --text-unit: var(--text-base-size); // if Em units → --text-unit: 1em; 28 | } 29 | 30 | :root, * { 31 | // type scale 32 | --text-xs: calc((var(--text-unit) / var(--text-scale-ratio)) / var(--text-scale-ratio)); 33 | --text-sm: calc(var(--text-xs) * var(--text-scale-ratio)); 34 | --text-md: calc(var(--text-sm) * var(--text-scale-ratio) * var(--text-scale-ratio)); 35 | --text-lg: calc(var(--text-md) * var(--text-scale-ratio)); 36 | --text-xl: calc(var(--text-lg) * var(--text-scale-ratio)); 37 | --text-xxl: calc(var(--text-xl) * var(--text-scale-ratio)); 38 | --text-xxxl: calc(var(--text-xxl) * var(--text-scale-ratio)); 39 | --text-xxxxl: calc(var(--text-xxxl) * var(--text-scale-ratio)); 40 | } 41 | 42 | 43 | @include breakpoint(md) { 44 | :root { 45 | --text-base-size: 1.25rem; 46 | --text-scale-ratio: 1.25; 47 | } 48 | } 49 | 50 | body { 51 | font-family: var(--font-primary); 52 | } 53 | 54 | h1, h2, h3, h4 { 55 | font-family: var(--font-secondary); 56 | --heading-font-weight: 700; 57 | } 58 | 59 | // font family 60 | .font-primary { font-family: var(--font-primary); } 61 | .font-secondary { font-family: var(--font-secondary); } 62 | 63 | // -------------------------------- 64 | 65 | // (END) Global editor code 66 | 67 | // -------------------------------- 68 | 69 | // link style 70 | a, .link {} 71 | 72 | mark { 73 | background-color: alpha(var(--color-accent), 0.2); 74 | color: inherit; 75 | } 76 | 77 | .text-component { 78 | --line-height-multiplier: 1; 79 | --text-space-y-multiplier: 1; 80 | 81 | > * { // use Em units 82 | --text-unit: 1em; 83 | --space-unit: 1em; 84 | } 85 | 86 | blockquote { 87 | padding-left: 1em; 88 | border-left: 4px solid var(--color-contrast-lower); 89 | font-style: italic; 90 | } 91 | 92 | hr { 93 | background: var(--color-contrast-lower); 94 | height: 1px; 95 | } 96 | 97 | figcaption { 98 | font-size: var(--text-sm); 99 | color: var(--color-contrast-low); 100 | } 101 | } 102 | 103 | .article { // e.g., blog posts 104 | --body-line-height: 1.58; // set body line-height 105 | --text-space-y-multiplier: 1.2; // control vertical spacing 106 | } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/custom-style/_util.scss: -------------------------------------------------------------------------------- 1 | @use '../base' as *; 2 | 3 | // -------------------------------- 4 | 5 | // How to create custom utility classes 👇 6 | 7 | // -------------------------------- 8 | 9 | // 👇 your custom utility class 10 | // .my-util-class { 11 | // property: value; 12 | // } 13 | 14 | // 👇 (optional) create responsive variations - edit only [my-util-class, property, value] 15 | // @each $breakpoint, $value in $breakpoints { 16 | // @include breakpoint(#{$breakpoint}) { 17 | // .my-util-class\@#{$breakpoint} { 18 | // property: value; 19 | // } 20 | // } 21 | // } -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | @use 'base' with ( 2 | $breakpoints: ( 3 | 'xs': 32rem, // ~512px 4 | 'sm': 48rem, // ~768px 5 | 'md': 64rem, // ~1024px 6 | 'lg': 80rem, // ~1280px 7 | 'xl': 90rem // ~1440px 8 | ), 9 | $grid-columns: 12 10 | ); 11 | 12 | /*! purgecss start ignore */ 13 | @use 'custom-style'; 14 | @use 'components/**/*.scss'; 15 | /*! purgecss end ignore */ -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/article-example-img-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/article-example-img-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/article-gallery-v3-author-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/article-gallery-v3-author-img-1.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/article-gallery-v3-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/article-gallery-v3-img-1.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/article-gallery-v3-img-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/article-gallery-v3-img-2.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/article-gallery-v3-img-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/article-gallery-v3-img-3.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/article-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/article-img-1.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/feature-v10-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/feature-v10-img-1.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/feature-v10-img-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/feature-v10-img-2.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/feature-v9-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/feature-v9-img-1.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/feature-v9-img-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/feature-v9-img-2.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/hero-diagonal-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/hero-diagonal-img-1.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/image-interest-points-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/image-interest-points-img-1.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/image-interest-points-img-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/image-interest-points-img-2.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/sticky-hero-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/sticky-hero-img-1.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/testimonial-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/testimonial-img-1.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/img/vertical-timeline-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-codyframe/main/assets/img/vertical-timeline-img-1.jpg -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_accordion.js: -------------------------------------------------------------------------------- 1 | // File#: _1_accordion 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | var Accordion = function(element) { 5 | this.element = element; 6 | this.items = Util.getChildrenByClassName(this.element, 'js-accordion__item'); 7 | this.version = this.element.getAttribute('data-version') ? '-'+this.element.getAttribute('data-version') : ''; 8 | this.showClass = 'accordion'+this.version+'__item--is-open'; 9 | this.animateHeight = (this.element.getAttribute('data-animation') == 'on'); 10 | this.multiItems = !(this.element.getAttribute('data-multi-items') == 'off'); 11 | // deep linking options 12 | this.deepLinkOn = this.element.getAttribute('data-deep-link') == 'on'; 13 | // init accordion 14 | this.initAccordion(); 15 | }; 16 | 17 | Accordion.prototype.initAccordion = function() { 18 | //set initial aria attributes 19 | for( var i = 0; i < this.items.length; i++) { 20 | var button = this.items[i].getElementsByTagName('button')[0], 21 | content = this.items[i].getElementsByClassName('js-accordion__panel')[0], 22 | isOpen = Util.hasClass(this.items[i], this.showClass) ? 'true' : 'false'; 23 | Util.setAttributes(button, {'aria-expanded': isOpen, 'aria-controls': 'accordion-content-'+i, 'id': 'accordion-header-'+i}); 24 | Util.addClass(button, 'js-accordion__trigger'); 25 | Util.setAttributes(content, {'aria-labelledby': 'accordion-header-'+i, 'id': 'accordion-content-'+i}); 26 | } 27 | 28 | //listen for Accordion events 29 | this.initAccordionEvents(); 30 | 31 | // check deep linking option 32 | this.initDeepLink(); 33 | }; 34 | 35 | Accordion.prototype.initAccordionEvents = function() { 36 | var self = this; 37 | 38 | this.element.addEventListener('click', function(event) { 39 | var trigger = event.target.closest('.js-accordion__trigger'); 40 | //check index to make sure the click didn't happen inside a children accordion 41 | if( trigger && Util.getIndexInArray(self.items, trigger.parentElement) >= 0) self.triggerAccordion(trigger); 42 | }); 43 | }; 44 | 45 | Accordion.prototype.triggerAccordion = function(trigger) { 46 | var bool = (trigger.getAttribute('aria-expanded') === 'true'); 47 | 48 | this.animateAccordion(trigger, bool, false); 49 | 50 | if(!bool && this.deepLinkOn) { 51 | history.replaceState(null, '', '#'+trigger.getAttribute('aria-controls')); 52 | } 53 | }; 54 | 55 | Accordion.prototype.animateAccordion = function(trigger, bool, deepLink) { 56 | var self = this; 57 | var item = trigger.closest('.js-accordion__item'), 58 | content = item.getElementsByClassName('js-accordion__panel')[0], 59 | ariaValue = bool ? 'false' : 'true'; 60 | 61 | if(!bool) Util.addClass(item, this.showClass); 62 | trigger.setAttribute('aria-expanded', ariaValue); 63 | self.resetContentVisibility(item, content, bool); 64 | 65 | if( !this.multiItems && !bool || deepLink) this.closeSiblings(item); 66 | }; 67 | 68 | Accordion.prototype.resetContentVisibility = function(item, content, bool) { 69 | Util.toggleClass(item, this.showClass, !bool); 70 | content.removeAttribute("style"); 71 | if(bool && !this.multiItems) { // accordion item has been closed -> check if there's one open to move inside viewport 72 | this.moveContent(); 73 | } 74 | }; 75 | 76 | Accordion.prototype.closeSiblings = function(item) { 77 | //if only one accordion can be open -> search if there's another one open 78 | var index = Util.getIndexInArray(this.items, item); 79 | for( var i = 0; i < this.items.length; i++) { 80 | if(Util.hasClass(this.items[i], this.showClass) && i != index) { 81 | this.animateAccordion(this.items[i].getElementsByClassName('js-accordion__trigger')[0], true, false); 82 | return false; 83 | } 84 | } 85 | }; 86 | 87 | Accordion.prototype.moveContent = function() { // make sure title of the accordion just opened is inside the viewport 88 | var openAccordion = this.element.getElementsByClassName(this.showClass); 89 | if(openAccordion.length == 0) return; 90 | var boundingRect = openAccordion[0].getBoundingClientRect(); 91 | if(boundingRect.top < 0 || boundingRect.top > window.innerHeight) { 92 | var windowScrollTop = window.scrollY || document.documentElement.scrollTop; 93 | window.scrollTo(0, boundingRect.top + windowScrollTop); 94 | } 95 | }; 96 | 97 | Accordion.prototype.initDeepLink = function() { 98 | if(!this.deepLinkOn) return; 99 | var hash = window.location.hash.substr(1); 100 | if(!hash || hash == '') return; 101 | var trigger = this.element.querySelector('.js-accordion__trigger[aria-controls="'+hash+'"]'); 102 | if(trigger && trigger.getAttribute('aria-expanded') !== 'true') { 103 | this.animateAccordion(trigger, false, true); 104 | setTimeout(function(){trigger.scrollIntoView(true);}); 105 | } 106 | }; 107 | 108 | window.Accordion = Accordion; 109 | 110 | //initialize the Accordion objects 111 | var accordions = document.getElementsByClassName('js-accordion'); 112 | if( accordions.length > 0 ) { 113 | for( var i = 0; i < accordions.length; i++) { 114 | (function(i){new Accordion(accordions[i]);})(i); 115 | } 116 | } 117 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_anim-menu-btn.js: -------------------------------------------------------------------------------- 1 | // File#: _1_anim-menu-btn 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | var menuBtns = document.getElementsByClassName('js-anim-menu-btn'); 5 | if( menuBtns.length > 0 ) { 6 | for(var i = 0; i < menuBtns.length; i++) {(function(i){ 7 | initMenuBtn(menuBtns[i]); 8 | })(i);} 9 | 10 | function initMenuBtn(btn) { 11 | btn.addEventListener('click', function(event){ 12 | event.preventDefault(); 13 | var status = !Util.hasClass(btn, 'anim-menu-btn--state-b'); 14 | Util.toggleClass(btn, 'anim-menu-btn--state-b', status); 15 | // emit custom event 16 | var event = new CustomEvent('anim-menu-btn-clicked', {detail: status}); 17 | btn.dispatchEvent(event); 18 | }); 19 | }; 20 | } 21 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_google-maps.js: -------------------------------------------------------------------------------- 1 | // File#: _1_google-maps 2 | // Usage: codyhouse.co/license 3 | function initGoogleMap() { 4 | var contactMap = document.getElementsByClassName('js-google-maps'); 5 | if(contactMap.length > 0) { 6 | for(var i = 0; i < contactMap.length; i++) { 7 | initContactMap(contactMap[i]); 8 | } 9 | } 10 | }; 11 | 12 | function initContactMap(wrapper) { 13 | var coordinate = wrapper.getAttribute('data-coordinates').split(','); 14 | var map = new google.maps.Map(wrapper, {zoom: 10, center: {lat: Number(coordinate[0]), lng: Number(coordinate[1])}}); 15 | var marker = new google.maps.Marker({position: {lat: Number(coordinate[0]), lng: Number(coordinate[1])}, map: map}); 16 | }; -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_immersive-section-transition.js: -------------------------------------------------------------------------------- 1 | // File#: _1_immersive-section-transition 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | var ImmerseSectionTr = function(element) { 5 | this.element = element; 6 | this.media = this.element.getElementsByClassName('js-immerse-section-tr__media'); 7 | this.scrollContent = this.element.getElementsByClassName('js-immerse-section-tr__content'); 8 | if(this.media.length < 1) return; 9 | this.figure = this.media[0].getElementsByClassName('js-immerse-section-tr__figure'); 10 | if(this.figure.length < 1) return; 11 | this.visibleFigure = false; 12 | this.mediaScale = 1; 13 | this.mediaInitHeight = 0; 14 | this.elementPadding = 0; 15 | this.scrollingFn = false; 16 | this.scrolling = false; 17 | this.active = false; 18 | this.scrollDelta = 0; // amount to scroll for full-screen scaleup 19 | initImmerseSectionTr(this); 20 | }; 21 | 22 | function initImmerseSectionTr(element) { 23 | initContainer(element); 24 | resetSection(element); 25 | 26 | // listen to resize event and reset values 27 | element.element.addEventListener('update-immerse-section', function(event){ 28 | resetSection(element); 29 | }); 30 | 31 | // detect when the element is sticky - update scale value and opacity layer 32 | var observer = new IntersectionObserver(immerseSectionTrCallback.bind(element)); 33 | observer.observe(element.media[0]); 34 | }; 35 | 36 | function resetSection(element) { 37 | getVisibleFigure(element); 38 | checkEffectActive(element); 39 | if(element.active) { 40 | Util.removeClass(element.element, 'immerse-section-tr--disabled'); 41 | updateMediaHeight(element); 42 | getMediaScale(element); 43 | updateMargin(element); 44 | setScaleValue.bind(element)(); 45 | } else { 46 | // reset appearance 47 | Util.addClass(element.element, 'immerse-section-tr--disabled'); 48 | element.media[0].style = ''; 49 | element.scrollContent[0].style = ''; 50 | updateScale(element, 1); 51 | updateOpacity(element, 0); 52 | } 53 | element.element.dispatchEvent(new CustomEvent('immersive-section-updated', {detail: {active: element.active, asset: element.visibleFigure}})); 54 | }; 55 | 56 | function getVisibleFigure(element) { // get visible figure element 57 | element.visibleFigure = false; 58 | for(var i = 0; i < element.figure.length; i++) { 59 | if(window.getComputedStyle(element.figure[i]).getPropertyValue('display') != 'none') { 60 | element.visibleFigure = element.figure[i]; 61 | break; 62 | } 63 | } 64 | }; 65 | 66 | function updateMediaHeight(element) { // set sticky element padding/margin + height 67 | element.mediaInitHeight = element.visibleFigure.offsetHeight; 68 | element.scrollDelta = (window.innerHeight - element.visibleFigure.offsetHeight) > (window.innerWidth - element.visibleFigure.offsetWidth) 69 | ? (window.innerHeight - element.visibleFigure.offsetHeight)/2 70 | : (window.innerWidth - element.visibleFigure.offsetWidth)/2; 71 | if(element.scrollDelta > window.innerHeight) element.scrollDelta = window.innerHeight; 72 | if(element.scrollDelta < 200) element.scrollDelta = 200; 73 | element.media[0].style.height = window.innerHeight+'px'; 74 | element.media[0].style.paddingTop = (window.innerHeight - element.visibleFigure.offsetHeight)/2+'px'; 75 | element.media[0].style.marginTop = (element.visibleFigure.offsetHeight - window.innerHeight)/2+'px'; 76 | }; 77 | 78 | function getMediaScale(element) { // get media final scale value 79 | var scaleX = roundValue(window.innerWidth/element.visibleFigure.offsetWidth), 80 | scaleY = roundValue(window.innerHeight/element.visibleFigure.offsetHeight); 81 | 82 | element.mediaScale = Math.max(scaleX, scaleY); 83 | element.elementPadding = parseInt(window.getComputedStyle(element.element).getPropertyValue('padding-top')); 84 | }; 85 | 86 | function roundValue(value) { 87 | return (Math.ceil(value*100)/100).toFixed(2); 88 | }; 89 | 90 | function updateMargin(element) { // update distance between media and content elements 91 | if(element.scrollContent.length > 0) element.scrollContent[0].style.marginTop = element.scrollDelta+'px'; 92 | }; 93 | 94 | function setScaleValue() { // update asset scale value 95 | if(!this.active) return; // effect is not active 96 | var offsetTop = (window.innerHeight - this.mediaInitHeight)/2; 97 | var top = this.element.getBoundingClientRect().top + this.elementPadding; 98 | 99 | if( top < offsetTop && top > offsetTop - this.scrollDelta) { 100 | var scale = 1 + (top - offsetTop)*(1 - this.mediaScale)/this.scrollDelta; 101 | updateScale(this, scale); 102 | updateOpacity(this, 0); 103 | } else if(top >= offsetTop) { 104 | updateScale(this, 1); 105 | updateOpacity(this, 0); 106 | } else { 107 | updateScale(this, this.mediaScale); 108 | updateOpacity(this, 1.8*( offsetTop - this.scrollDelta - top)/ window.innerHeight); 109 | } 110 | 111 | this.scrolling = false; 112 | }; 113 | 114 | function updateScale(element, value) { // apply new scale value 115 | element.visibleFigure.style.transform = 'scale('+value+')'; 116 | element.visibleFigure.style.msTransform = 'scale('+value+')'; 117 | }; 118 | 119 | function updateOpacity(element, value) { // update layer opacity 120 | element.element.style.setProperty('--immerse-section-tr-opacity', value); 121 | }; 122 | 123 | function immerseSectionTrCallback(entries) { // intersectionObserver callback 124 | if(entries[0].isIntersecting) { 125 | if(this.scrollingFn) return; // listener for scroll event already added 126 | immerseSectionTrScrollEvent(this); 127 | } else { 128 | if(!this.scrollingFn) return; // listener for scroll event already removed 129 | window.removeEventListener('scroll', this.scrollingFn); 130 | this.scrollingFn = false; 131 | } 132 | }; 133 | 134 | function immerseSectionTrScrollEvent(element) { // listen to scroll when asset element is inside the viewport 135 | element.scrollingFn = immerseSectionTrScrolling.bind(element); 136 | window.addEventListener('scroll', element.scrollingFn); 137 | }; 138 | 139 | function immerseSectionTrScrolling() { // update asset scale on scroll 140 | if(this.scrolling) return; 141 | this.scrolling = true; 142 | window.requestAnimationFrame(setScaleValue.bind(this)); 143 | }; 144 | 145 | function initContainer(element) { 146 | // add a padding to the container to fix the collapsing-margin issue 147 | if(parseInt(window.getComputedStyle(element.element).getPropertyValue('padding-top')) == 0) element.element.style.paddingTop = '1px'; 148 | }; 149 | 150 | function checkEffectActive(element) { //check if effect needs to be activated 151 | element.active = true; 152 | if(element.visibleFigure.offsetHeight >= window.innerHeight) element.active = false; 153 | if( window.innerHeight - element.visibleFigure.offsetHeight >= 600) element.active = false; 154 | }; 155 | 156 | //initialize the ImmerseSectionTr objects 157 | var immerseSections = document.getElementsByClassName('js-immerse-section-tr'), 158 | reducedMotion = Util.osHasReducedMotion(), 159 | intObserverSupported = ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype); 160 | 161 | if(immerseSections.length < 1 ) return; 162 | if( !reducedMotion && intObserverSupported) { 163 | var immerseSectionsArray = []; 164 | for( var i = 0; i < immerseSections.length; i++) { 165 | (function(i){immerseSectionsArray.push(new ImmerseSectionTr(immerseSections[i]));})(i); 166 | } 167 | 168 | if(immerseSectionsArray.length > 0) { 169 | var resizingId = false, 170 | customEvent = new CustomEvent('update-immerse-section'); 171 | 172 | window.addEventListener('resize', function() { 173 | clearTimeout(resizingId); 174 | resizingId = setTimeout(doneResizing, 500); 175 | }); 176 | 177 | function doneResizing() { 178 | for( var i = 0; i < immerseSectionsArray.length; i++) { 179 | (function(i){immerseSectionsArray[i].element.dispatchEvent(customEvent)})(i); 180 | }; 181 | }; 182 | }; 183 | } else { // effect deactivated 184 | for( var i = 0; i < immerseSections.length; i++) Util.addClass(immerseSections[i], 'immerse-section-tr--disabled'); 185 | } 186 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_modal-window.js: -------------------------------------------------------------------------------- 1 | // File#: _1_modal-window 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | var Modal = function(element) { 5 | this.element = element; 6 | this.triggers = document.querySelectorAll('[aria-controls="'+this.element.getAttribute('id')+'"]'); 7 | this.firstFocusable = null; 8 | this.lastFocusable = null; 9 | this.moveFocusEl = null; // focus will be moved to this element when modal is open 10 | this.modalFocus = this.element.getAttribute('data-modal-first-focus') ? this.element.querySelector(this.element.getAttribute('data-modal-first-focus')) : null; 11 | this.selectedTrigger = null; 12 | this.preventScrollEl = this.getPreventScrollEl(); 13 | this.showClass = "modal--is-visible"; 14 | this.initModal(); 15 | }; 16 | 17 | Modal.prototype.getPreventScrollEl = function() { 18 | var scrollEl = false; 19 | var querySelector = this.element.getAttribute('data-modal-prevent-scroll'); 20 | if(querySelector) scrollEl = document.querySelector(querySelector); 21 | return scrollEl; 22 | }; 23 | 24 | Modal.prototype.initModal = function() { 25 | var self = this; 26 | //open modal when clicking on trigger buttons 27 | if ( this.triggers ) { 28 | for(var i = 0; i < this.triggers.length; i++) { 29 | this.triggers[i].addEventListener('click', function(event) { 30 | event.preventDefault(); 31 | if(Util.hasClass(self.element, self.showClass)) { 32 | self.closeModal(); 33 | return; 34 | } 35 | self.selectedTrigger = event.target; 36 | self.showModal(); 37 | self.initModalEvents(); 38 | }); 39 | } 40 | } 41 | 42 | // listen to the openModal event -> open modal without a trigger button 43 | this.element.addEventListener('openModal', function(event){ 44 | if(event.detail) self.selectedTrigger = event.detail; 45 | self.showModal(); 46 | self.initModalEvents(); 47 | }); 48 | 49 | // listen to the closeModal event -> close modal without a trigger button 50 | this.element.addEventListener('closeModal', function(event){ 51 | if(event.detail) self.selectedTrigger = event.detail; 52 | self.closeModal(); 53 | }); 54 | 55 | // if modal is open by default -> initialise modal events 56 | if(Util.hasClass(this.element, this.showClass)) this.initModalEvents(); 57 | }; 58 | 59 | Modal.prototype.showModal = function() { 60 | var self = this; 61 | Util.addClass(this.element, this.showClass); 62 | this.getFocusableElements(); 63 | if(this.moveFocusEl) { 64 | this.moveFocusEl.focus(); 65 | // wait for the end of transitions before moving focus 66 | this.element.addEventListener("transitionend", function cb(event) { 67 | self.moveFocusEl.focus(); 68 | self.element.removeEventListener("transitionend", cb); 69 | }); 70 | } 71 | this.emitModalEvents('modalIsOpen'); 72 | // change the overflow of the preventScrollEl 73 | if(this.preventScrollEl) this.preventScrollEl.style.overflow = 'hidden'; 74 | }; 75 | 76 | Modal.prototype.closeModal = function() { 77 | if(!Util.hasClass(this.element, this.showClass)) return; 78 | console.log('close') 79 | Util.removeClass(this.element, this.showClass); 80 | this.firstFocusable = null; 81 | this.lastFocusable = null; 82 | this.moveFocusEl = null; 83 | if(this.selectedTrigger) this.selectedTrigger.focus(); 84 | //remove listeners 85 | this.cancelModalEvents(); 86 | this.emitModalEvents('modalIsClose'); 87 | // change the overflow of the preventScrollEl 88 | if(this.preventScrollEl) this.preventScrollEl.style.overflow = ''; 89 | }; 90 | 91 | Modal.prototype.initModalEvents = function() { 92 | //add event listeners 93 | this.element.addEventListener('keydown', this); 94 | this.element.addEventListener('click', this); 95 | }; 96 | 97 | Modal.prototype.cancelModalEvents = function() { 98 | //remove event listeners 99 | this.element.removeEventListener('keydown', this); 100 | this.element.removeEventListener('click', this); 101 | }; 102 | 103 | Modal.prototype.handleEvent = function (event) { 104 | switch(event.type) { 105 | case 'click': { 106 | this.initClick(event); 107 | } 108 | case 'keydown': { 109 | this.initKeyDown(event); 110 | } 111 | } 112 | }; 113 | 114 | Modal.prototype.initKeyDown = function(event) { 115 | if( event.keyCode && event.keyCode == 9 || event.key && event.key == 'Tab' ) { 116 | //trap focus inside modal 117 | this.trapFocus(event); 118 | } else if( (event.keyCode && event.keyCode == 13 || event.key && event.key == 'Enter') && event.target.closest('.js-modal__close')) { 119 | event.preventDefault(); 120 | this.closeModal(); // close modal when pressing Enter on close button 121 | } 122 | }; 123 | 124 | Modal.prototype.initClick = function(event) { 125 | //close modal when clicking on close button or modal bg layer 126 | if( !event.target.closest('.js-modal__close') && !Util.hasClass(event.target, 'js-modal') ) return; 127 | event.preventDefault(); 128 | this.closeModal(); 129 | }; 130 | 131 | Modal.prototype.trapFocus = function(event) { 132 | if( this.firstFocusable == document.activeElement && event.shiftKey) { 133 | //on Shift+Tab -> focus last focusable element when focus moves out of modal 134 | event.preventDefault(); 135 | this.lastFocusable.focus(); 136 | } 137 | if( this.lastFocusable == document.activeElement && !event.shiftKey) { 138 | //on Tab -> focus first focusable element when focus moves out of modal 139 | event.preventDefault(); 140 | this.firstFocusable.focus(); 141 | } 142 | } 143 | 144 | Modal.prototype.getFocusableElements = function() { 145 | //get all focusable elements inside the modal 146 | var allFocusable = this.element.querySelectorAll(focusableElString); 147 | this.getFirstVisible(allFocusable); 148 | this.getLastVisible(allFocusable); 149 | this.getFirstFocusable(); 150 | }; 151 | 152 | Modal.prototype.getFirstVisible = function(elements) { 153 | //get first visible focusable element inside the modal 154 | for(var i = 0; i < elements.length; i++) { 155 | if( isVisible(elements[i]) ) { 156 | this.firstFocusable = elements[i]; 157 | break; 158 | } 159 | } 160 | }; 161 | 162 | Modal.prototype.getLastVisible = function(elements) { 163 | //get last visible focusable element inside the modal 164 | for(var i = elements.length - 1; i >= 0; i--) { 165 | if( isVisible(elements[i]) ) { 166 | this.lastFocusable = elements[i]; 167 | break; 168 | } 169 | } 170 | }; 171 | 172 | Modal.prototype.getFirstFocusable = function() { 173 | if(!this.modalFocus || !Element.prototype.matches) { 174 | this.moveFocusEl = this.firstFocusable; 175 | return; 176 | } 177 | var containerIsFocusable = this.modalFocus.matches(focusableElString); 178 | if(containerIsFocusable) { 179 | this.moveFocusEl = this.modalFocus; 180 | } else { 181 | this.moveFocusEl = false; 182 | var elements = this.modalFocus.querySelectorAll(focusableElString); 183 | for(var i = 0; i < elements.length; i++) { 184 | if( isVisible(elements[i]) ) { 185 | this.moveFocusEl = elements[i]; 186 | break; 187 | } 188 | } 189 | if(!this.moveFocusEl) this.moveFocusEl = this.firstFocusable; 190 | } 191 | }; 192 | 193 | Modal.prototype.emitModalEvents = function(eventName) { 194 | var event = new CustomEvent(eventName, {detail: this.selectedTrigger}); 195 | this.element.dispatchEvent(event); 196 | }; 197 | 198 | function isVisible(element) { 199 | return element.offsetWidth || element.offsetHeight || element.getClientRects().length; 200 | }; 201 | 202 | window.Modal = Modal; 203 | 204 | //initialize the Modal objects 205 | var modals = document.getElementsByClassName('js-modal'); 206 | // generic focusable elements string selector 207 | var focusableElString = '[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex]:not([tabindex="-1"]), [contenteditable], audio[controls], video[controls], summary'; 208 | if( modals.length > 0 ) { 209 | var modalArrays = []; 210 | for( var i = 0; i < modals.length; i++) { 211 | (function(i){modalArrays.push(new Modal(modals[i]));})(i); 212 | } 213 | 214 | window.addEventListener('keydown', function(event){ //close modal window on esc 215 | if(event.keyCode && event.keyCode == 27 || event.key && event.key.toLowerCase() == 'escape') { 216 | for( var i = 0; i < modalArrays.length; i++) { 217 | (function(i){modalArrays[i].closeModal();})(i); 218 | }; 219 | } 220 | }); 221 | } 222 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_notice.js: -------------------------------------------------------------------------------- 1 | // File#: _1_notice 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | function initNoticeEvents(notice) { 5 | notice.addEventListener('click', function(event){ 6 | if(event.target.closest('.js-notice__hide-control')) { 7 | event.preventDefault(); 8 | Util.addClass(notice, 'notice--hide'); 9 | } 10 | }); 11 | }; 12 | 13 | var noticeElements = document.getElementsByClassName('js-notice'); 14 | if(noticeElements.length > 0) { 15 | for(var i=0; i < noticeElements.length; i++) {(function(i){ 16 | initNoticeEvents(noticeElements[i]); 17 | })(i);} 18 | } 19 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_reading-progressbar.js: -------------------------------------------------------------------------------- 1 | // File#: _1_reading-progressbar 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | var readingIndicator = document.getElementsByClassName('js-reading-progressbar')[0], 5 | readingIndicatorContent = document.getElementsByClassName('js-reading-content')[0]; 6 | 7 | if( readingIndicator && readingIndicatorContent) { 8 | var progressInfo = [], 9 | progressEvent = false, 10 | progressFallback = readingIndicator.getElementsByClassName('js-reading-progressbar__fallback')[0], 11 | progressIsSupported = 'value' in readingIndicator; 12 | 13 | var boundingClientRect = readingIndicatorContent.getBoundingClientRect(); 14 | 15 | progressInfo['height'] = readingIndicatorContent.offsetHeight; 16 | progressInfo['top'] = boundingClientRect.top; 17 | progressInfo['bottom'] = boundingClientRect.bottom; 18 | progressInfo['window'] = window.innerHeight; 19 | progressInfo['class'] = 'reading-progressbar--is-active'; 20 | progressInfo['hideClass'] = 'reading-progressbar--is-out'; 21 | 22 | //init indicator 23 | setProgressIndicator(); 24 | // wait for font to be loaded - reset progress bar 25 | if(document.fonts) { 26 | document.fonts.ready.then(function() { 27 | triggerReset(); 28 | }); 29 | } 30 | // listen to window resize - update progress 31 | window.addEventListener('resize', function(event){ 32 | triggerReset(); 33 | }); 34 | 35 | //listen to the window scroll event - update progress 36 | window.addEventListener('scroll', function(event){ 37 | if(progressEvent) return; 38 | progressEvent = true; 39 | (!window.requestAnimationFrame) ? setTimeout(function(){setProgressIndicator();}, 250) : window.requestAnimationFrame(setProgressIndicator); 40 | }); 41 | 42 | function setProgressIndicator() { 43 | var boundingClientRect = readingIndicatorContent.getBoundingClientRect(); 44 | progressInfo['top'] = boundingClientRect.top; 45 | progressInfo['bottom'] = boundingClientRect.bottom; 46 | 47 | if(progressInfo['height'] <= progressInfo['window']) { 48 | // short content - hide progress indicator 49 | Util.removeClass(readingIndicator, progressInfo['class']); 50 | progressEvent = false; 51 | return; 52 | } 53 | // get new progress and update element 54 | Util.addClass(readingIndicator, progressInfo['class']); 55 | var value = (progressInfo['top'] >= 0) ? 0 : 100*(0 - progressInfo['top'])/(progressInfo['height'] - progressInfo['window']); 56 | readingIndicator.setAttribute('value', value); 57 | if(!progressIsSupported && progressFallback) progressFallback.style.width = value+'%'; 58 | // hide progress bar when target is outside the viewport 59 | Util.toggleClass(readingIndicator, progressInfo['hideClass'], progressInfo['bottom'] <= 0); 60 | progressEvent = false; 61 | }; 62 | 63 | function triggerReset() { 64 | if(progressEvent) return; 65 | progressEvent = true; 66 | (!window.requestAnimationFrame) ? setTimeout(function(){resetProgressIndicator();}, 250) : window.requestAnimationFrame(resetProgressIndicator); 67 | }; 68 | 69 | function resetProgressIndicator() { 70 | progressInfo['height'] = readingIndicatorContent.offsetHeight; 71 | progressInfo['window'] = window.innerHeight; 72 | setProgressIndicator(); 73 | }; 74 | } 75 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_reveal-effects.js: -------------------------------------------------------------------------------- 1 | // File#: _1_reveal-effects 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | var fxElements = document.getElementsByClassName('reveal-fx'); 5 | var intersectionObserverSupported = ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype); 6 | if(fxElements.length > 0) { 7 | // deactivate effect if Reduced Motion is enabled 8 | if (Util.osHasReducedMotion() || !intersectionObserverSupported) { 9 | fxRemoveClasses(); 10 | return; 11 | } 12 | //on small devices, do not animate elements -> reveal all 13 | if( fxDisabled(fxElements[0]) ) { 14 | fxRevealAll(); 15 | return; 16 | } 17 | 18 | var fxRevealDelta = 120; // amount (in pixel) the element needs to enter the viewport to be revealed - if not custom value (data-reveal-fx-delta) 19 | 20 | var viewportHeight = window.innerHeight, 21 | fxChecking = false, 22 | fxRevealedItems = [], 23 | fxElementDelays = fxGetDelays(), //elements animation delay 24 | fxElementDeltas = fxGetDeltas(); // amount (in px) the element needs enter the viewport to be revealed (default value is fxRevealDelta) 25 | 26 | 27 | // add event listeners 28 | window.addEventListener('load', fxReveal); 29 | window.addEventListener('resize', fxResize); 30 | window.addEventListener('restartAll', fxRestart); 31 | 32 | // observe reveal elements 33 | var observer = []; 34 | initObserver(); 35 | 36 | function initObserver() { 37 | for(var i = 0; i < fxElements.length; i++) { 38 | observer[i] = new IntersectionObserver( 39 | function(entries, observer) { 40 | if(entries[0].isIntersecting) { 41 | fxRevealItemObserver(entries[0].target); 42 | observer.unobserve(entries[0].target); 43 | } 44 | }, 45 | {rootMargin: "0px 0px -"+fxElementDeltas[i]+"px 0px"} 46 | ); 47 | 48 | observer[i].observe(fxElements[i]); 49 | } 50 | }; 51 | 52 | function fxRevealAll() { // reveal all elements - small devices 53 | for(var i = 0; i < fxElements.length; i++) { 54 | Util.addClass(fxElements[i], 'reveal-fx--is-visible'); 55 | } 56 | }; 57 | 58 | function fxResize() { // on resize - check new window height and reveal visible elements 59 | if(fxChecking) return; 60 | fxChecking = true; 61 | (!window.requestAnimationFrame) ? setTimeout(function(){fxReset();}, 250) : window.requestAnimationFrame(fxReset); 62 | }; 63 | 64 | function fxReset() { 65 | viewportHeight = window.innerHeight; 66 | fxReveal(); 67 | }; 68 | 69 | function fxReveal() { // reveal visible elements 70 | for(var i = 0; i < fxElements.length; i++) {(function(i){ 71 | if(fxRevealedItems.indexOf(i) != -1 ) return; //element has already been revelead 72 | if(fxElementIsVisible(fxElements[i], i)) { 73 | fxRevealItem(i); 74 | fxRevealedItems.push(i); 75 | }})(i); 76 | } 77 | fxResetEvents(); 78 | fxChecking = false; 79 | }; 80 | 81 | function fxRevealItem(index) { 82 | if(fxElementDelays[index] && fxElementDelays[index] != 0) { 83 | // wait before revealing element if a delay was added 84 | setTimeout(function(){ 85 | Util.addClass(fxElements[index], 'reveal-fx--is-visible'); 86 | }, fxElementDelays[index]); 87 | } else { 88 | Util.addClass(fxElements[index], 'reveal-fx--is-visible'); 89 | } 90 | }; 91 | 92 | function fxRevealItemObserver(item) { 93 | var index = Util.getIndexInArray(fxElements, item); 94 | if(fxRevealedItems.indexOf(index) != -1 ) return; //element has already been revelead 95 | fxRevealItem(index); 96 | fxRevealedItems.push(index); 97 | fxResetEvents(); 98 | fxChecking = false; 99 | }; 100 | 101 | function fxGetDelays() { // get anmation delays 102 | var delays = []; 103 | for(var i = 0; i < fxElements.length; i++) { 104 | delays.push( fxElements[i].getAttribute('data-reveal-fx-delay') ? parseInt(fxElements[i].getAttribute('data-reveal-fx-delay')) : 0); 105 | } 106 | return delays; 107 | }; 108 | 109 | function fxGetDeltas() { // get reveal delta 110 | var deltas = []; 111 | for(var i = 0; i < fxElements.length; i++) { 112 | deltas.push( fxElements[i].getAttribute('data-reveal-fx-delta') ? parseInt(fxElements[i].getAttribute('data-reveal-fx-delta')) : fxRevealDelta); 113 | } 114 | return deltas; 115 | }; 116 | 117 | function fxDisabled(element) { // check if elements need to be animated - no animation on small devices 118 | return !(window.getComputedStyle(element, '::before').getPropertyValue('content').replace(/'|"/g, "") == 'reveal-fx'); 119 | }; 120 | 121 | function fxElementIsVisible(element, i) { // element is inside viewport 122 | return (fxGetElementPosition(element) <= viewportHeight - fxElementDeltas[i]); 123 | }; 124 | 125 | function fxGetElementPosition(element) { // get top position of element 126 | return element.getBoundingClientRect().top; 127 | }; 128 | 129 | function fxResetEvents() { 130 | if(fxElements.length > fxRevealedItems.length) return; 131 | // remove event listeners if all elements have been revealed 132 | window.removeEventListener('load', fxReveal); 133 | window.removeEventListener('resize', fxResize); 134 | }; 135 | 136 | function fxRemoveClasses() { 137 | // Reduced Motion on or Intersection Observer not supported 138 | while(fxElements[0]) { 139 | // remove all classes starting with 'reveal-fx--' 140 | var classes = fxElements[0].getAttribute('class').split(" ").filter(function(c) { 141 | return c.lastIndexOf('reveal-fx--', 0) !== 0; 142 | }); 143 | fxElements[0].setAttribute('class', classes.join(" ").trim()); 144 | Util.removeClass(fxElements[0], 'reveal-fx'); 145 | } 146 | }; 147 | 148 | function fxRestart() { 149 | // restart the reveal effect -> hide all elements and re-init the observer 150 | if (Util.osHasReducedMotion() || !intersectionObserverSupported || fxDisabled(fxElements[0])) { 151 | return; 152 | } 153 | // check if we need to add the event listensers back 154 | if(fxElements.length <= fxRevealedItems.length) { 155 | window.addEventListener('load', fxReveal); 156 | window.addEventListener('resize', fxResize); 157 | } 158 | // remove observer and reset the observer array 159 | for(var i = 0; i < observer.length; i++) { 160 | if(observer[i]) observer[i].disconnect(); 161 | } 162 | observer = []; 163 | // remove visible class 164 | for(var i = 0; i < fxElements.length; i++) { 165 | Util.removeClass(fxElements[i], 'reveal-fx--is-visible'); 166 | } 167 | // reset fxRevealedItems array 168 | fxRevealedItems = []; 169 | // restart observer 170 | initObserver(); 171 | }; 172 | } 173 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_skip-link.js: -------------------------------------------------------------------------------- 1 | // File#: _1_skip-link 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | function initSkipLinkEvents(skipLink) { 5 | // toggle class skip-link--focus if link is in focus/loses focus 6 | skipLink.addEventListener('focusin', function(){ 7 | Util.addClass(skipLink, 'skip-link--focus'); 8 | }); 9 | skipLink.addEventListener('focusout', function(){ 10 | Util.removeClass(skipLink, 'skip-link--focus'); 11 | }); 12 | }; 13 | 14 | var skipLinks = document.getElementsByClassName('skip-link'); 15 | if( skipLinks.length > 0 ) { 16 | for( var i = 0; i < skipLinks.length; i++) { 17 | initSkipLinkEvents(skipLinks[i]); 18 | } 19 | } 20 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_social-sharing.js: -------------------------------------------------------------------------------- 1 | // File#: _1_social-sharing 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | function initSocialShare(button) { 5 | button.addEventListener('click', function(event){ 6 | event.preventDefault(); 7 | var social = button.getAttribute('data-social'); 8 | var url = getSocialUrl(button, social); 9 | (social == 'mail') 10 | ? window.location.href = url 11 | : window.open(url, social+'-share-dialog', 'width=626,height=436'); 12 | }); 13 | }; 14 | 15 | function getSocialUrl(button, social) { 16 | var params = getSocialParams(social); 17 | var newUrl = ''; 18 | for(var i = 0; i < params.length; i++) { 19 | var paramValue = button.getAttribute('data-'+params[i]); 20 | if(params[i] == 'hashtags') paramValue = encodeURI(paramValue.replace(/\#| /g, '')); 21 | if(paramValue) { 22 | (social == 'facebook') 23 | ? newUrl = newUrl + 'u='+encodeURIComponent(paramValue)+'&' 24 | : newUrl = newUrl + params[i]+'='+encodeURIComponent(paramValue)+'&'; 25 | } 26 | } 27 | if(social == 'linkedin') newUrl = 'mini=true&'+newUrl; 28 | return button.getAttribute('href')+'?'+newUrl; 29 | }; 30 | 31 | function getSocialParams(social) { 32 | var params = []; 33 | switch (social) { 34 | case 'twitter': 35 | params = ['text', 'hashtags']; 36 | break; 37 | case 'facebook': 38 | case 'linkedin': 39 | params = ['url']; 40 | break; 41 | case 'pinterest': 42 | params = ['url', 'media', 'description']; 43 | break; 44 | case 'mail': 45 | params = ['subject', 'body']; 46 | break; 47 | } 48 | return params; 49 | }; 50 | 51 | var socialShare = document.getElementsByClassName('js-social-share'); 52 | if(socialShare.length > 0) { 53 | for( var i = 0; i < socialShare.length; i++) { 54 | (function(i){initSocialShare(socialShare[i])})(i); 55 | } 56 | } 57 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_sticky-hero.js: -------------------------------------------------------------------------------- 1 | // File#: _1_sticky-hero 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | var StickyBackground = function(element) { 5 | this.element = element; 6 | this.scrollingElement = this.element.getElementsByClassName('sticky-hero__content')[0]; 7 | this.nextElement = this.element.nextElementSibling; 8 | this.scrollingTreshold = 0; 9 | this.nextTreshold = 0; 10 | initStickyEffect(this); 11 | }; 12 | 13 | function initStickyEffect(element) { 14 | var observer = new IntersectionObserver(stickyCallback.bind(element), { threshold: [0, 0.1, 1] }); 15 | observer.observe(element.scrollingElement); 16 | if(element.nextElement) observer.observe(element.nextElement); 17 | }; 18 | 19 | function stickyCallback(entries, observer) { 20 | var threshold = entries[0].intersectionRatio.toFixed(1); 21 | (entries[0].target == this.scrollingElement) 22 | ? this.scrollingTreshold = threshold 23 | : this.nextTreshold = threshold; 24 | 25 | Util.toggleClass(this.element, 'sticky-hero--media-is-fixed', (this.nextTreshold > 0 || this.scrollingTreshold > 0)); 26 | }; 27 | 28 | 29 | var stickyBackground = document.getElementsByClassName('js-sticky-hero'), 30 | intersectionObserverSupported = ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype); 31 | if(stickyBackground.length > 0 && intersectionObserverSupported) { // if IntersectionObserver is not supported, animations won't be triggeres 32 | for(var i = 0; i < stickyBackground.length; i++) { 33 | (function(i){ // if animations are enabled -> init the StickyBackground object 34 | if( Util.hasClass(stickyBackground[i], 'sticky-hero--overlay-layer') || Util.hasClass(stickyBackground[i], 'sticky-hero--scale')) new StickyBackground(stickyBackground[i]); 35 | })(i); 36 | } 37 | } 38 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_1_vertical-timeline.js: -------------------------------------------------------------------------------- 1 | // File#: _1_vertical-timeline 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | var VTimeline = function(element) { 5 | this.element = element; 6 | this.sections = this.element.getElementsByClassName('js-v-timeline__section'); 7 | this.animate = this.element.getAttribute('data-animation') && this.element.getAttribute('data-animation') == 'on' ? true : false; 8 | this.animationClass = 'v-timeline__section--animate'; 9 | this.animationDelta = '-150px'; 10 | initVTimeline(this); 11 | }; 12 | 13 | function initVTimeline(element) { 14 | if(!element.animate) return; 15 | for(var i = 0; i < element.sections.length; i++) { 16 | var observer = new IntersectionObserver(vTimelineCallback.bind(element, i), 17 | {rootMargin: "0px 0px "+element.animationDelta+" 0px"}); 18 | observer.observe(element.sections[i]); 19 | } 20 | }; 21 | 22 | function vTimelineCallback(index, entries, observer) { 23 | if(entries[0].isIntersecting) { 24 | Util.addClass(this.sections[index], this.animationClass); 25 | observer.unobserve(this.sections[index]); 26 | } 27 | }; 28 | 29 | //initialize the VTimeline objects 30 | var timelines = document.querySelectorAll('.js-v-timeline'), 31 | intersectionObserverSupported = ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype), 32 | reducedMotion = Util.osHasReducedMotion(); 33 | if( timelines.length > 0) { 34 | for( var i = 0; i < timelines.length; i++) { 35 | if(intersectionObserverSupported && !reducedMotion) (function(i){new VTimeline(timelines[i]);})(i); 36 | else timelines[i].removeAttribute('data-animation'); 37 | } 38 | } 39 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_2_flexi-header.js: -------------------------------------------------------------------------------- 1 | // File#: _2_flexi-header 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | var flexHeader = document.getElementsByClassName('js-f-header'); 5 | if(flexHeader.length > 0) { 6 | var menuTrigger = flexHeader[0].getElementsByClassName('js-anim-menu-btn')[0], 7 | firstFocusableElement = getMenuFirstFocusable(); 8 | 9 | // we'll use these to store the node that needs to receive focus when the mobile menu is closed 10 | var focusMenu = false; 11 | 12 | resetFlexHeaderOffset(); 13 | setAriaButtons(); 14 | 15 | menuTrigger.addEventListener('anim-menu-btn-clicked', function(event){ 16 | toggleMenuNavigation(event.detail); 17 | }); 18 | 19 | // listen for key events 20 | window.addEventListener('keyup', function(event){ 21 | // listen for esc key 22 | if( (event.keyCode && event.keyCode == 27) || (event.key && event.key.toLowerCase() == 'escape' )) { 23 | // close navigation on mobile if open 24 | if(menuTrigger.getAttribute('aria-expanded') == 'true' && isVisible(menuTrigger)) { 25 | focusMenu = menuTrigger; // move focus to menu trigger when menu is close 26 | menuTrigger.click(); 27 | } 28 | } 29 | // listen for tab key 30 | if( (event.keyCode && event.keyCode == 9) || (event.key && event.key.toLowerCase() == 'tab' )) { 31 | // close navigation on mobile if open when nav loses focus 32 | if(menuTrigger.getAttribute('aria-expanded') == 'true' && isVisible(menuTrigger) && !document.activeElement.closest('.js-f-header')) menuTrigger.click(); 33 | } 34 | }); 35 | 36 | // detect click on a dropdown control button - expand-on-mobile only 37 | flexHeader[0].addEventListener('click', function(event){ 38 | var btnLink = event.target.closest('.js-f-header__dropdown-control'); 39 | if(!btnLink) return; 40 | !btnLink.getAttribute('aria-expanded') ? btnLink.setAttribute('aria-expanded', 'true') : btnLink.removeAttribute('aria-expanded'); 41 | }); 42 | 43 | // detect mouseout from a dropdown control button - expand-on-mobile only 44 | flexHeader[0].addEventListener('mouseout', function(event){ 45 | var btnLink = event.target.closest('.js-f-header__dropdown-control'); 46 | if(!btnLink) return; 47 | // check layout type 48 | if(getLayout() == 'mobile') return; 49 | btnLink.removeAttribute('aria-expanded'); 50 | }); 51 | 52 | // close dropdown on focusout - expand-on-mobile only 53 | flexHeader[0].addEventListener('focusin', function(event){ 54 | var btnLink = event.target.closest('.js-f-header__dropdown-control'), 55 | dropdown = event.target.closest('.f-header__dropdown'); 56 | if(dropdown) return; 57 | if(btnLink && btnLink.hasAttribute('aria-expanded')) return; 58 | // check layout type 59 | if(getLayout() == 'mobile') return; 60 | var openDropdown = flexHeader[0].querySelector('.js-f-header__dropdown-control[aria-expanded="true"]'); 61 | if(openDropdown) openDropdown.removeAttribute('aria-expanded'); 62 | }); 63 | 64 | // listen for resize 65 | var resizingId = false; 66 | window.addEventListener('resize', function() { 67 | clearTimeout(resizingId); 68 | resizingId = setTimeout(doneResizing, 500); 69 | }); 70 | 71 | function getMenuFirstFocusable() { 72 | var focusableEle = flexHeader[0].getElementsByClassName('f-header__nav')[0].querySelectorAll('[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex]:not([tabindex="-1"]), [contenteditable], audio[controls], video[controls], summary'), 73 | firstFocusable = false; 74 | for(var i = 0; i < focusableEle.length; i++) { 75 | if( focusableEle[i].offsetWidth || focusableEle[i].offsetHeight || focusableEle[i].getClientRects().length ) { 76 | firstFocusable = focusableEle[i]; 77 | break; 78 | } 79 | } 80 | 81 | return firstFocusable; 82 | }; 83 | 84 | function isVisible(element) { 85 | return (element.offsetWidth || element.offsetHeight || element.getClientRects().length); 86 | }; 87 | 88 | function doneResizing() { 89 | if( !isVisible(menuTrigger) && Util.hasClass(flexHeader[0], 'f-header--expanded')) { 90 | menuTrigger.click(); 91 | } 92 | resetFlexHeaderOffset(); 93 | }; 94 | 95 | function toggleMenuNavigation(bool) { // toggle menu visibility on small devices 96 | Util.toggleClass(document.getElementsByClassName('f-header__nav')[0], 'f-header__nav--is-visible', bool); 97 | Util.toggleClass(flexHeader[0], 'f-header--expanded', bool); 98 | menuTrigger.setAttribute('aria-expanded', bool); 99 | if(bool) firstFocusableElement.focus(); // move focus to first focusable element 100 | else if(focusMenu) { 101 | focusMenu.focus(); 102 | focusMenu = false; 103 | } 104 | }; 105 | 106 | function resetFlexHeaderOffset() { 107 | // on mobile -> update max height of the flexi header based on its offset value (e.g., if there's a fixed pre-header element) 108 | document.documentElement.style.setProperty('--f-header-offset', flexHeader[0].getBoundingClientRect().top+'px'); 109 | }; 110 | 111 | function setAriaButtons() { 112 | var btnDropdown = flexHeader[0].getElementsByClassName('js-f-header__dropdown-control'); 113 | for(var i = 0; i < btnDropdown.length; i++) { 114 | var id = 'f-header-dropdown-'+i, 115 | dropdown = btnDropdown[i].nextElementSibling; 116 | if(dropdown.hasAttribute('id')) { 117 | id = dropdown.getAttribute('id'); 118 | } else { 119 | dropdown.setAttribute('id', id); 120 | } 121 | btnDropdown[i].setAttribute('aria-controls', id); 122 | } 123 | }; 124 | 125 | function getLayout() { 126 | return getComputedStyle(flexHeader[0], ':before').getPropertyValue('content').replace(/\'|"/g, ''); 127 | }; 128 | } 129 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_2_image-interest-points.js: -------------------------------------------------------------------------------- 1 | // File#: _2_points-of-interest 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | function initPoi(element) { 5 | element.addEventListener('click', function(event){ 6 | var poiItem = event.target.closest('.js-poi__item'); 7 | if(poiItem) Util.addClass(poiItem, 'poi__item--visited'); 8 | }); 9 | }; 10 | 11 | var poi = document.getElementsByClassName('js-poi'); 12 | for(var i = 0; i < poi.length; i++) { 13 | (function(i){initPoi(poi[i]);})(i); 14 | } 15 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_2_pricing-table.js: -------------------------------------------------------------------------------- 1 | // File#: _2_pricing-table 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | // NOTE: you need the js code only when using the --has-switch variation of the pricing table 5 | // default version does not require js 6 | var pTable = document.getElementsByClassName('js-p-table--has-switch'); 7 | if(pTable.length > 0) { 8 | for(var i = 0; i < pTable.length; i++) { 9 | (function(i){ addPTableEvent(pTable[i]);})(i); 10 | } 11 | 12 | function addPTableEvent(element) { 13 | var pSwitch = element.getElementsByClassName('js-p-table__switch')[0]; 14 | if(pSwitch) { 15 | pSwitch.addEventListener('change', function(event) { 16 | Util.toggleClass(element, 'p-table--yearly', (event.target.value == 'yearly')); 17 | }); 18 | } 19 | } 20 | } 21 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/main/assets/js/components/_2_sticky-sharebar.js: -------------------------------------------------------------------------------- 1 | // File#: _2_sticky-sharebar 2 | // Usage: codyhouse.co/license 3 | (function() { 4 | var StickyShareBar = function(element) { 5 | this.element = element; 6 | this.contentTarget = document.getElementsByClassName('js-sticky-sharebar-target'); 7 | this.contentTargetOut = document.getElementsByClassName('js-sticky-sharebar-target-out'); 8 | this.showClass = 'sticky-sharebar--on-target'; 9 | this.threshold = '50%'; // Share Bar will be revealed when .js-sticky-sharebar-target element reaches 50% of the viewport 10 | initShareBar(this); 11 | initTargetOut(this); 12 | }; 13 | 14 | function initShareBar(shareBar) { 15 | if(shareBar.contentTarget.length < 1) { 16 | shareBar.showSharebar = true; 17 | Util.addClass(shareBar.element, shareBar.showClass); 18 | return; 19 | } 20 | if(intersectionObserverSupported) { 21 | shareBar.showSharebar = false; 22 | initObserver(shareBar); // update anchor appearance on scroll 23 | } else { 24 | Util.addClass(shareBar.element, shareBar.showClass); 25 | } 26 | }; 27 | 28 | function initObserver(shareBar) { // target of Sharebar 29 | var observer = new IntersectionObserver( 30 | function(entries, observer) { 31 | shareBar.showSharebar = entries[0].isIntersecting; 32 | toggleSharebar(shareBar); 33 | }, 34 | {rootMargin: "0px 0px -"+shareBar.threshold+" 0px"} 35 | ); 36 | observer.observe(shareBar.contentTarget[0]); 37 | }; 38 | 39 | function initTargetOut(shareBar) { // target out of Sharebar 40 | shareBar.hideSharebar = false; 41 | if(shareBar.contentTargetOut.length < 1) { 42 | return; 43 | } 44 | var observer = new IntersectionObserver( 45 | function(entries, observer) { 46 | shareBar.hideSharebar = entries[0].isIntersecting; 47 | toggleSharebar(shareBar); 48 | } 49 | ); 50 | observer.observe(shareBar.contentTargetOut[0]); 51 | }; 52 | 53 | function toggleSharebar(shareBar) { 54 | Util.toggleClass(shareBar.element, shareBar.showClass, shareBar.showSharebar && !shareBar.hideSharebar); 55 | }; 56 | 57 | //initialize the StickyShareBar objects 58 | var stickyShareBar = document.getElementsByClassName('js-sticky-sharebar'), 59 | intersectionObserverSupported = ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype); 60 | 61 | if( stickyShareBar.length > 0 ) { 62 | for( var i = 0; i < stickyShareBar.length; i++) { 63 | (function(i){ new StickyShareBar(stickyShareBar[i]); })(i); 64 | } 65 | } 66 | }()); -------------------------------------------------------------------------------- /virgo-codyframe/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "virgo", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "gulp": "gulp", 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "devDependencies": { 9 | "autoprefixer": "^9.4.3", 10 | "browser-sync": "^2.26.3", 11 | "codyhouse-framework": "^3.0.0", 12 | "gulp": "^4.0.0", 13 | "gulp-clean-css": "^4.3.0", 14 | "gulp-concat": "^2.6.1", 15 | "gulp-postcss": "^8.0.0", 16 | "gulp-purgecss": "^3.0.0", 17 | "gulp-rename": "^1.4.0", 18 | "gulp-sass": "^5.0.0", 19 | "gulp-sass-glob": "git+https://github.com/CodyHouse/gulp-sass-glob", 20 | "gulp-uglify": "^3.0.2", 21 | "postcss-calc": "^7.0.1", 22 | "postcss-css-variables": "git+https://github.com/CodyHouse/postcss-css-variables", 23 | "sass-embedded": "^1.0.0-beta.4" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/article-example-img-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/article-example-img-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/article-gallery-v3-author-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/article-gallery-v3-author-img-1.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/article-gallery-v3-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/article-gallery-v3-img-1.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/article-gallery-v3-img-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/article-gallery-v3-img-2.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/article-gallery-v3-img-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/article-gallery-v3-img-3.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/article-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/article-img-1.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/feature-v10-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/feature-v10-img-1.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/feature-v10-img-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/feature-v10-img-2.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/feature-v9-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/feature-v9-img-1.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/feature-v9-img-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/feature-v9-img-2.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/hero-diagonal-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/hero-diagonal-img-1.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/image-interest-points-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/image-interest-points-img-1.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/image-interest-points-img-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/image-interest-points-img-2.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/sticky-hero-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/sticky-hero-img-1.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/testimonial-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/testimonial-img-1.jpg -------------------------------------------------------------------------------- /virgo-tailwind/assets/img/vertical-timeline-img-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codyhouse/virgo-template/9c239de0649a56c0c0bba4198fa1e26d41725537/virgo-tailwind/assets/img/vertical-timeline-img-1.jpg -------------------------------------------------------------------------------- /virgo-tailwind/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ["./src/**/*.{html,js}"], 3 | theme: { 4 | colors: { 5 | transparent: 'transparent', 6 | current: 'currentColor', 7 | inherit: 'inherit', 8 | primary: { 9 | DEFAULT: 'hsl(var(--color-primary) / )', 10 | darker: 'hsl(var(--color-primary-darker) / )', 11 | dark: 'hsl(var(--color-primary-dark) / )', 12 | light: 'hsl(var(--color-primary-light) / )', 13 | lighter: 'hsl(var(--color-primary-lighter) / )', 14 | }, 15 | accent: { 16 | DEFAULT: 'hsl(var(--color-accent) / )', 17 | darker: 'hsl(var(--color-accent-darker) / )', 18 | dark: 'hsl(var(--color-accent-dark) / )', 19 | light: 'hsl(var(--color-accent-light) / )', 20 | lighter: 'hsl(var(--color-accent-lighter) / )', 21 | }, 22 | black: 'hsl(var(--color-black) / )', 23 | white: 'hsl(var(--color-white) / )', 24 | warning: { 25 | DEFAULT: 'hsl(var(--color-warning) / )', 26 | darker: 'hsl(var(--color-warning-darker) / )', 27 | dark: 'hsl(var(--color-warning-dark) / )', 28 | light: 'hsl(var(--color-warning-light) / )', 29 | lighter: 'hsl(var(--color-warning-lighter) / )', 30 | }, 31 | success: { 32 | DEFAULT: 'hsl(var(--color-success) / )', 33 | darker: 'hsl(var(--color-success-darker) / )', 34 | dark: 'hsl(var(--color-success-dark) / )', 35 | light: 'hsl(var(--color-success-light) / )', 36 | lighter: 'hsl(var(--color-success-lighter) / )', 37 | }, 38 | error: { 39 | DEFAULT: 'hsl(var(--color-error) / )', 40 | darker: 'hsl(var(--color-error-darker) / )', 41 | dark: 'hsl(var(--color-error-dark) / )', 42 | light: 'hsl(var(--color-error-light) / )', 43 | lighter: 'hsl(var(--color-error-lighter) / )', 44 | }, 45 | floor: { 46 | DEFAULT: 'hsl(var(--color-floor) / )', 47 | darker: 'hsl(var(--color-floor-darker) / )', 48 | dark: 'hsl(var(--color-floor-dark) / )', 49 | light: 'hsl(var(--color-floor-light) / )', 50 | lighter: 'hsl(var(--color-floor-lighter) / )', 51 | }, 52 | contrast: { 53 | lower: 'hsl(var(--color-contrast-lower) / )', 54 | low: 'hsl(var(--color-contrast-low) / )', 55 | medium: 'hsl(var(--color-contrast-medium) / )', 56 | high: 'hsl(var(--color-contrast-high) / )', 57 | higher: 'hsl(var(--color-contrast-higher) / )', 58 | }, 59 | }, 60 | extend: { 61 | fontFamily: { 62 | 'primary': ['Inter', 'system-ui', 'sans-serif'], 63 | 'secondary': ['Playfair Display', 'serif'], 64 | }, 65 | zIndex: { 66 | '1': '1', 67 | '2': '2', 68 | '3': '3', 69 | '5': '5', 70 | '15': '15', 71 | }, 72 | borderRadius: { 73 | 'inherit': 'inherit', 74 | }, 75 | lineHeight: { 76 | 'extra-tight': '1.1', 77 | }, 78 | boxShadow: { 79 | 'inner-xs': 'inset 0 0 0.5px 1px hsla(0, 0%, 100%, 0.075), 0 0.1px 0.3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.12)', 80 | 'inner-2xs': 'inset 0 0 0.5px 1px hsla(0, 0%, 100%, 0.075), 0 0.1px 0.3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.12), 0 0.1px 0.3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.12)', 81 | 'inner-sm': 'inset 0 0 0.5px 1px hsla(0, 0%, 100%, 0.075), 0 0.3px 0.4px rgba(0, 0, 0, 0.025), 0 0.9px 1.5px rgba(0, 0, 0, 0.05), 0 3.5px 6px rgba(0, 0, 0, 0.1)', 82 | 'inner-md': 'inset 0 0 0.5px 1px hsla(0, 0%, 100%, 0.075), 0 0.9px 1.5px rgba(0, 0, 0, 0.03), 0 3.1px 5.5px rgba(0, 0, 0, 0.08), 0 14px 25px rgba(0, 0, 0, 0.12)', 83 | 'inner-lg': 'inset 0 0 0.5px 1px hsla(0, 0%, 100%, 0.075), 0 1.2px 1.9px -1px rgba(0, 0, 0, 0.014), 0 3.3px 5.3px -1px rgba(0, 0, 0, 0.038), 0 8.5px 12.7px -1px rgba(0, 0, 0, 0.085), 0 30px 42px -1px rgba(0, 0, 0, 0.15)', 84 | 'inner-top-xs': 'inset 0 1px 0.5px hsla(0, 0%, 100%, 0.075), 0 0.1px 0.3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.12)', 85 | 'inner-top-sm': 'inset 0 1px 0.5px hsla(0, 0%, 100%, 0.075), 0 0.3px 0.4px rgba(0, 0, 0, 0.025), 0 0.9px 1.5px rgba(0, 0, 0, 0.05), 0 3.5px 6px rgba(0, 0, 0, 0.1)', 86 | 'inner-top-md': 'inset 0 1px 0.5px hsla(0, 0%, 100%, 0.075), 0 0.9px 1.5px rgba(0, 0, 0, 0.03), 0 3.1px 5.5px rgba(0, 0, 0, 0.08), 0 14px 25px rgba(0, 0, 0, 0.12)', 87 | 'inner-top-lg': 'inset 0 1px 0.5px hsla(0, 0%, 100%, 0.075), 0 1.2px 1.9px -1px rgba(0, 0, 0, 0.014), 0 3.3px 5.3px -1px rgba(0, 0, 0, 0.038), 0 8.5px 12.7px -1px rgba(0, 0, 0, 0.085), 0 30px 42px -1px rgba(0, 0, 0, 0.15)', 88 | 89 | }, 90 | opacity: { 91 | '7': '.07', 92 | '8': '.08', 93 | '9': '.09', 94 | '12': '.12', 95 | '15': '.15', 96 | '35': '.35', 97 | '65': '.65', 98 | '85': '.85', 99 | '98': '.98', 100 | }, 101 | borderWidth: { 102 | '1': '1px', 103 | '3': '3px', 104 | }, 105 | outlineWidth: { 106 | '3': '3px', 107 | }, 108 | }, 109 | }, 110 | plugins: [ 111 | require('@tailwindcss/aspect-ratio'), 112 | ], 113 | } --------------------------------------------------------------------------------