diff --git a/_scripts/pages/download.js b/_scripts/pages/download.js index dfc254ac60..5ef9c08dc6 100644 --- a/_scripts/pages/download.js +++ b/_scripts/pages/download.js @@ -93,7 +93,7 @@ Promise.all([config, jQuery, openDownloadOverlay]).then(([config, $, openDownloa $('#download').text(translateDownload) } } - $('#choice-buttons').on('click', updateDownloadButton) + $('#choice-buttons button').on('click', updateDownloadButton) $('#choice-buttons input').on('input', updateDownloadButton) updateDownloadButton() diff --git a/_scripts/widgets/showcase.js b/_scripts/widgets/showcase.js index 88c43b42ed..5594d27aa8 100644 --- a/_scripts/widgets/showcase.js +++ b/_scripts/widgets/showcase.js @@ -43,16 +43,16 @@ export default class Showcase { start () { for (let i = 0; i < this.slides.length; i++) { const n = this.slides[i] - const $iChoice = $("[href$='" + n + "']", this.container) + const $iChoice = $("[aria-controls='" + n + "']", this.container) const $iContainer = $('#' + n, this.container) - $iContainer.prepend('
') + $iContainer.prepend('') // each choice button const that = this $iChoice.on('click', function (e) { e.preventDefault() - that.slideTo($(this).attr('href').split('#').pop()) // slide on click of button + that.slideTo($(this).attr('aria-controls')) // slide on click of button }) } @@ -98,10 +98,68 @@ export default class Showcase { return console.error("could not find requested slide '" + rSlide + "'") // log an error } + const $container = $(this.container) + + // update aria-expanded to alert which slide is active + $container.find('button[aria-controls]').each(function() { + const $button = $(this) + if ($button.attr('aria-controls') === rSlide) { + $button.attr('aria-expanded', true) + } + else { + $button.attr('aria-expanded', false) + } + }) + + // we want to only mark them as hidden after some time has elapsed + // this allows us to keep the slide height animation + let $targetsToHide = []; + let $targetToFocus = false; + + /** + * unhide a specific jQuery element + * + * we first set the hidden attribute to false, so that the DOM tree + * can update. we then set the active class on the next frame to allow + * the animation to play nicely + * + * @param {*} $target + */ + const unhide = function($target) { + $target.attr('hidden', false) + requestAnimationFrame(function() { + $target.addClass('active') + }) + $target.find('.showcase-back').attr('tabindex', 0) + } + + /** + * hide a specific jQuery element + * + * we don't need to worry about any animation frames here! + * + * @param {*} $target + */ + const hide = function($target) { + $target.removeClass('active') + $target.find('.showcase-back').attr('tabindex', -1) + $targetsToHide.push($target) + } + + const $indexSlide = $(this.index, this.container) + if (rSlide === 'index') { - $(this.index, this.container).addClass('active') + unhide($indexSlide) + + if (this.current) { + // focus the previous button when returning to the index + $targetToFocus = $('button[aria-controls="' + this.current + '"]') + } + else { + $targetToFocus = $(this.index) + } } else { - $(this.index, this.container).removeClass('active') + hide($indexSlide) } // iterates through slides based on this.slides @@ -110,24 +168,33 @@ export default class Showcase { const $n = $('#' + n, this.container) // current iterated slide if (n === rSlide) { // if correct slide - $n.addClass('active') + unhide($n) + $targetToFocus = $n } else { - $n.removeClass('active') + hide($n) } } this.current = rSlide - $(this.container).trigger('change', { + $container.trigger('change', { active: rSlide }) if (this.current !== 'index') { $('body').animate({ - scrollTop: $(this.container).offset().top + scrollTop: $container.offset().top }, 100) } this.resize() // resize the container + + // hide and focus roughly after animations are complete + $container.one('transitionend', function() { + for (const $target of $targetsToHide) { + $target.attr('hidden', true) + } + $targetToFocus.focus() + }) } /** diff --git a/_styles/home.css b/_styles/home.css index f8de69c741..5c92322b98 100644 --- a/_styles/home.css +++ b/_styles/home.css @@ -165,7 +165,6 @@ input:focus + .focus-reveal { } #showcase > div { - display: block; margin: auto; width: 100%; padding: 0 24px; @@ -220,6 +219,17 @@ input:focus + .focus-reveal { color: inherit; } +#showcase button { + background-color: transparent; + border: 0; + box-shadow: none; + background-image: none; + padding: 0; + margin: 0; + color: inherit; + text-shadow: inherit; +} + /******************** * showcase programs * ********************/ diff --git a/_styles/main.css b/_styles/main.css index 6f12259c5f..518b021c3d 100644 --- a/_styles/main.css +++ b/_styles/main.css @@ -47,11 +47,16 @@ body { **************/ a { - color: #08c; - fill: #08c; + color: #007dbc; + fill: #007dbc; text-decoration: none; } +section.grey a { + color: #0079b6; + fill: #0079b6; +} + a:focus { text-decoration: underline; } @@ -175,11 +180,11 @@ img.inline + div.inline { margin-left: 12px; } -.read-more { +.read-more button { white-space: nowrap; } -.read-more::after { +.read-more button::after { color: inherit; /* Encoded `→`, see: https://github.com/elementary/website/issues/2851 */ @@ -191,7 +196,8 @@ img.inline + div.inline { transition: transform 0.15s ease-in-out; } -.read-more:hover::after { +.read-more button:hover::after, +.read-more button:focus::after { transform: translateX(3px); } diff --git a/images/icons/actions/symbolic/appointment-symbolic.svg b/images/icons/actions/symbolic/appointment-symbolic.svg index 343be92538..b8c5628729 100644 --- a/images/icons/actions/symbolic/appointment-symbolic.svg +++ b/images/icons/actions/symbolic/appointment-symbolic.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/icons/actions/symbolic/edit-clear-all-symbolic.svg b/images/icons/actions/symbolic/edit-clear-all-symbolic.svg index db90bce878..3f7f6d55a7 100644 --- a/images/icons/actions/symbolic/edit-clear-all-symbolic.svg +++ b/images/icons/actions/symbolic/edit-clear-all-symbolic.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/icons/devices/symbolic/audio-input-microphone-symbolic.svg b/images/icons/devices/symbolic/audio-input-microphone-symbolic.svg index 5834a1cd53..2e91f26681 100644 --- a/images/icons/devices/symbolic/audio-input-microphone-symbolic.svg +++ b/images/icons/devices/symbolic/audio-input-microphone-symbolic.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/icons/status/symbolic/changes-prevent-symbolic.svg b/images/icons/status/symbolic/changes-prevent-symbolic.svg index 31b464254f..d82ee5261a 100644 --- a/images/icons/status/symbolic/changes-prevent-symbolic.svg +++ b/images/icons/status/symbolic/changes-prevent-symbolic.svg @@ -1 +1 @@ - + diff --git a/images/logotype-os.svg b/images/logotype-os.svg index 1bdd0cde61..5b8e56f98f 100644 --- a/images/logotype-os.svg +++ b/images/logotype-os.svg @@ -1 +1 @@ - \ No newline at end of file +elementary OS \ No newline at end of file diff --git a/images/thirdparty-icons/apps/symbolic/flatpak.svg b/images/thirdparty-icons/apps/symbolic/flatpak.svg index eba75f509a..43249c0f20 100644 --- a/images/thirdparty-icons/apps/symbolic/flatpak.svg +++ b/images/thirdparty-icons/apps/symbolic/flatpak.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/thirdparty-icons/apps/symbolic/internet-web-browser-symbolic.svg b/images/thirdparty-icons/apps/symbolic/internet-web-browser-symbolic.svg index e08fe56115..d2124d4230 100644 --- a/images/thirdparty-icons/apps/symbolic/internet-web-browser-symbolic.svg +++ b/images/thirdparty-icons/apps/symbolic/internet-web-browser-symbolic.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/thirdparty-logos/ars.svg b/images/thirdparty-logos/ars.svg index 72ab678507..bec4aa4251 100644 --- a/images/thirdparty-logos/ars.svg +++ b/images/thirdparty-logos/ars.svg @@ -1 +1 @@ - \ No newline at end of file +Ars Technica Logo \ No newline at end of file diff --git a/images/thirdparty-logos/forbes.svg b/images/thirdparty-logos/forbes.svg index 2b0d48ac72..44240612a9 100644 --- a/images/thirdparty-logos/forbes.svg +++ b/images/thirdparty-logos/forbes.svg @@ -1 +1 @@ - \ No newline at end of file +Forbes Logo \ No newline at end of file diff --git a/images/thirdparty-logos/lifehacker.svg b/images/thirdparty-logos/lifehacker.svg index b397ecccd0..39aaa05257 100644 --- a/images/thirdparty-logos/lifehacker.svg +++ b/images/thirdparty-logos/lifehacker.svg @@ -1 +1 @@ - \ No newline at end of file +Lifehacker Logo \ No newline at end of file diff --git a/images/thirdparty-logos/maclife.svg b/images/thirdparty-logos/maclife.svg index 888679096c..944ed097ee 100644 --- a/images/thirdparty-logos/maclife.svg +++ b/images/thirdparty-logos/maclife.svg @@ -1 +1 @@ - \ No newline at end of file +Mac|Life Logo \ No newline at end of file diff --git a/images/thirdparty-logos/wired.svg b/images/thirdparty-logos/wired.svg index d695c86e71..0638d2b64a 100644 --- a/images/thirdparty-logos/wired.svg +++ b/images/thirdparty-logos/wired.svg @@ -1 +1 @@ - \ No newline at end of file +WIRED Logo \ No newline at end of file diff --git a/index.php b/index.php index c5177ac6a9..15192838a8 100644 --- a/index.php +++ b/index.php @@ -85,7 +85,7 @@
-

+

@@ -175,37 +175,37 @@
-
+
-

Multitasking View

+

Multitasking View

Workspaces help organize your work by task. Keep work and play separate, but just one swipe or tap away.

-
+
Videos screenshot
-

Picture-in-Picture

+

Picture-in-Picture

Whether you’re watching a movie, game, or terminal process, Picture-in-Picture helps keep tabs on one thing while working on another.

-
+
Code screenshot
- +
- +
- +
-

Do Not Disturb

+

Do Not Disturb

Tune everything else out to stay focused on your work, or keep notifications at bay while watching a movie. Do Not Disturb stops notifications in their tracks.

@@ -218,23 +218,23 @@

elementary OS comes with a carefully considered set of apps that cater to everyday needs so you can spend more time using your computer and less time cleaning up bloatware.

-
+