diff --git a/app/assets/images/ico-soil.svg b/app/assets/images/ico-soil.svg new file mode 100644 index 0000000..35dccce --- /dev/null +++ b/app/assets/images/ico-soil.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 52b622e..49e8de9 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -267,6 +267,10 @@ main { --clr-action: var(--clr-white); } +.stage { + --clr-bg: var(--clr-sand-light); + --clr-action: var(--clr-white); +} .hero-container, .carousel { @@ -278,7 +282,7 @@ main { display: grid; grid-template: 1fr / 1fr; - & img { + & img, video { grid-area: 1 / 1; width: 100%; height: 100%; @@ -287,11 +291,32 @@ main { min-height: 0; } + & article { + grid-area: 1 / 1; + place-self: start start; + z-index: 1; + } + + &:has(video) { + color: var(--clr-white); + + & h2 { + text-align: left; + margin-top: 1em; + } + } + + & svg { grid-area: 1 / 1; place-self: end end; fill: var(--clr-bg, var(--clr-green)); } + + & .hero-link { + grid-area: 1 / 1; + z-index: 2; + } } .cta { @@ -358,4 +383,33 @@ main { background-color: var(--clr-black); } } +} + +.stage-header { + background-color: var(--clr-bg); + padding: 1rem; + display: flex; + gap: 0.5rem; + align-items: center; + + & h1 { + font: var(--td-base); + margin: 0; + } +} + +.stage-icon { + width: 2.5rem; + aspect-ratio: 1; + background-color: var(--clr-green); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} + +.stage-progress { + font: var(--td-s); + text-transform: uppercase; + font-weight: 700; } \ No newline at end of file diff --git a/app/controllers/site_controller.rb b/app/controllers/site_controller.rb index 51470ea..bf2e03e 100644 --- a/app/controllers/site_controller.rb +++ b/app/controllers/site_controller.rb @@ -16,6 +16,16 @@ class SiteController < ApplicationController end + def intro + @node = root_node&.children&.intro&.first + end + + + def stage + @node = root_node&.children&.stage&.first + end + + private def root_node diff --git a/app/javascript/application.js b/app/javascript/application.js index 21741f6..9057320 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -3,11 +3,13 @@ import { Application } from "@hotwired/stimulus" import LanguageMenuController from "language_menu_controller" import CarouselController from "carousel_controller" +import IntroController from "intro_controller" const application = Application.start() application.register("language-menu", LanguageMenuController) application.register("carousel", CarouselController) +application.register("intro", IntroController) // Configure Stimulus development experience application.debug = false diff --git a/app/javascript/intro_controller.js b/app/javascript/intro_controller.js new file mode 100644 index 0000000..905c44d --- /dev/null +++ b/app/javascript/intro_controller.js @@ -0,0 +1,17 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["video", "link"] + + connect() { + this.videoTarget.addEventListener("ended", this.followLink) + } + + disconnect() { + this.videoTarget.removeEventListener("ended", this.followLink) + } + + followLink = () => { + this.linkTarget.click() + } +} diff --git a/app/models/node.rb b/app/models/node.rb index 3f1a59c..28b43e1 100644 --- a/app/models/node.rb +++ b/app/models/node.rb @@ -27,7 +27,9 @@ class Node < ApplicationRecord enum :template, { start: 0, - facts: 1 + facts: 1, + intro: 2, + stage: 3 } def available_templates @@ -35,7 +37,7 @@ class Node < ApplicationRecord case depth when 1 - [ :facts ] + [ :facts, :intro, :stage ] when 2 [] else diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 186fa0b..c503512 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -17,7 +17,7 @@ <%= stylesheet_link_tag "reset", "application" %> - <%= frontend_javascript_importmap_tags %w[application @hotwired/turbo-rails @hotwired/stimulus language_menu_controller carousel_controller] %> + <%= frontend_javascript_importmap_tags %w[application @hotwired/turbo-rails @hotwired/stimulus language_menu_controller carousel_controller intro_controller] %> <%= content_for :header %> diff --git a/app/views/site/facts.html.erb b/app/views/site/facts.html.erb index acfde73..f9ca869 100644 --- a/app/views/site/facts.html.erb +++ b/app/views/site/facts.html.erb @@ -28,6 +28,6 @@
- <%= link_to tag.span(t("game.got_it_lets_get_started")), {action: "facts"}, class: "cta" %> + <%= link_to tag.span(t("game.got_it_lets_get_started")), {action: "intro"}, class: "cta" %>
diff --git a/app/views/site/intro.html.erb b/app/views/site/intro.html.erb new file mode 100644 index 0000000..2aa0695 --- /dev/null +++ b/app/views/site/intro.html.erb @@ -0,0 +1,21 @@ +<%- content_for :title, node_title(@node) %> + +<% video_attachment = @node.attachments.select { |a| a.asset&.file&.video? }[0] %> + +
+ <% if video_attachment %> + <%= video_tag rails_storage_proxy_path(video_attachment.asset.file), + autoplay: true, + muted: true, + loop: false, + playsinline: true, + preload: "auto", + data: { intro_target: "video" } %> + +
+ <%= video_attachment.body.html_safe %> +
+ <% end %> + + <%= link_to url_for(action: "stage", id: 1), class: "hero-link", "aria-label": t("game.got_it_lets_get_started"), data: { intro_target: "link" } do %><% end %> +
\ No newline at end of file diff --git a/app/views/site/stage.html.erb b/app/views/site/stage.html.erb new file mode 100644 index 0000000..77c7278 --- /dev/null +++ b/app/views/site/stage.html.erb @@ -0,0 +1,21 @@ +<%- content_for :title, node_title(@node) %> + +
+
+ <%= svg "ico-soil" %> +
+
+ <%= tag.div t("game.stage_i_of_n", i: 1, n: 5), class: "stage-progress" %> + <%= tag.h1 @node.title %> +
+
+ +
+ <%= render_responsive_picture(@node.icon, alt: "Hero", fetchpriority: "high") %> + <%= svg "ico-wave" %> +
+ +
+ <%= tag.h1 t("game.intro_title").html_safe %> + +
diff --git a/config/importmap.rb b/config/importmap.rb index 2514c7a..416b4cb 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -16,3 +16,4 @@ pin "tom-select", to: "tom-select--dist--js--tom-select.base.min.js.js" # @2.4.3 pin "application", preload: false pin "language_menu_controller", preload: false pin "carousel_controller", preload: false +pin "intro_controller", preload: false diff --git a/config/locales/en.yml b/config/locales/en.yml index 923c50d..8100664 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -15,7 +15,8 @@ en: play_time: Play time 2-5 minutes go_to_slide: Go to slide - got_it_lets_get_started: Got it, let’s get started + got_it_lets_get_started: Got it, let’s get started + stage_i_of_n: Stage %{i} of %{n} countries: au: Australia @@ -273,6 +274,8 @@ en: templates: start: Start facts: Facts + intro: Intro + stage: Stage categories: diff --git a/config/routes.rb b/config/routes.rb index 563f027..865a20e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -59,7 +59,12 @@ Rails.application.routes.draw do scope ":locale", constraints: { locale: /en|zh|hr|cs|da|nl|fi|fr|fr-CA|de|hu|it|ja|ko|nb|pl|pt|ro|sr|sk|sl|es|sv|uk/ } do # get "*url", to: "site#page", constraints: lambda { |req| req.path.exclude?("storage") } + get "facts", to: "site#facts" + get "intro", to: "site#intro" + + get "stage/:id", to: "site#stage" + get "", to: "site#index", as: :locale_root end