Merge pull request #8873 from MiroslavDionisiev/UEPR-90

feat: [UEPR-90] Added new section to the ideas page
This commit is contained in:
Miroslav Dionisiev 2024-11-14 11:39:45 +02:00 committed by GitHub
commit 0cc1091e46
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 376 additions and 433 deletions

View file

@ -60,6 +60,7 @@ $active-dark-gray: hsla(0, 0%, 0%, .2);
$box-shadow-gray: hsla(0, 0%, 0%, .25);
$box-shadow-light-gray: hsla(0, 0%, 0%, .15);
$overlay-gray: hsla(0, 0%, 0%, .75);
$gray-50: hsla(226, 15%, 97%, 1);
$transparent-light-blue: rgba(229, 240, 254, 0);
/* Typography Colors */

View file

@ -1,284 +1,261 @@
const bindAll = require('lodash.bindall');
const FormattedMessage = require('react-intl').FormattedMessage;
const injectIntl = require('react-intl').injectIntl;
const React = require('react');
const Button = require('../../components/forms/button.jsx');
const FlexRow = require('../../components/flex-row/flex-row.jsx');
const MasonryGrid = require('../../components/masonrygrid/masonrygrid.jsx');
const TitleBanner = require('../../components/title-banner/title-banner.jsx');
const TTTModal = require('../../components/modal/ttt/modal.jsx');
const TTTTile = require('../../components/ttt-tile/ttt-tile.jsx');
const Page = require('../../components/page/www/page.jsx');
const intlShape = require('../../lib/intl-shape');
const render = require('../../lib/render.jsx');
const Tiles = require('./ttt.json');
const {useIntl} = require('react-intl');
require('./ideas.scss');
class Ideas extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
'handleShowTTTModal',
'handleHideTTTModal',
'renderTiles'
]);
this.state = {
currentTile: Tiles[0],
TTTModalOpen: false
};
const tipsSectionData = [
{
tipImage: {
altTextId: 'ideas.gettingStartedImageDescription',
imageSrc: '/images/ideas/getting-started-illustration.svg'
},
button: {
href: '/projects/editor/?tutorial=getStarted',
buttonTextId: 'ideas.gettingStartedButtonText'
}
},
{
tipImage: {
altTextId: 'ideas.seeTutorialsLibraryImageDescription',
imageSrc: '/images/ideas/see-tutorials-library.png'
},
button: {
href: '/projects/editor/?tutorial=all',
buttonTextId: 'ideas.seeTutorialsLibraryButtonText'
}
},
{
tipImage: {
altTextId: 'ideas.starterProjectsImageDescription',
imageSrc: '/images/ideas/starter-projects-illustration.svg'
},
button: {
href: '/starter_projects',
buttonTextId: 'ideas.starterProjectsButton'
}
},
{
tipImage: {
altTextId: 'ideas.cardsIllustrationDescription',
imageSrc: '/images/ideas/cards-illustration.svg'
},
button: {
hrefId: 'cards.scratch-cards-allLink',
buttonImageSrc: '/images/ideas/download-icon.svg',
buttonTextId: 'ideas.codingCards'
}
}
handleShowTTTModal (tile) {
// expects translated tile
this.setState({
currentTile: tile,
TTTModalOpen: true
});
];
const physicalIdeasData = [
{
physicalIdeasImage: {
imageSrc: '/images/ideas/micro-bit.png',
imageClass: 'micro-bit'
},
physicalIdeasDescription: {
headerId: 'ideas.microBitHeader',
bodyId: 'ideas.microBitBody',
hrefId: 'cards.microbit-cardsLink',
buttonImageSrc: '/images/ideas/download-icon.svg',
buttonTextId: 'ideas.codingCards'
}
},
{
physicalIdeasImage: {
imageSrc: '/images/ideas/make-board.svg',
imageClass: 'makey-makey-img'
},
physicalIdeasDescription: {
headerId: 'ideas.makeyMakeyHeader',
bodyId: 'ideas.makeyMakeyBody',
hrefId: 'cards.makeymakey-cardsLink',
buttonImageSrc: '/images/ideas/download-icon.svg',
buttonTextId: 'ideas.codingCards'
}
}
handleHideTTTModal () {
this.setState({
TTTModalOpen: false
});
}
renderTiles () {
return Tiles.map((tile, key) => {
const translatedTile = {
tutorialUrl: `/projects/editor/?tutorial=${tile.tutorialUrl}`,
modalImage: tile.modalImage,
modalImageDescription: this.props.intl.formatMessage({id: tile.modalImageDescription}),
description: this.props.intl.formatMessage({id: tile.description}),
guideUrl: this.props.intl.formatMessage({id: tile.guideUrl}),
thumbImage: tile.thumbImage,
thumbImageDescription: this.props.intl.formatMessage({id: tile.thumbImageDescription}),
title: this.props.intl.formatMessage({id: tile.title}),
cardsUrl: this.props.intl.formatMessage({id: tile.cardsUrl})
};
return (
<TTTTile
key={key}
onClick={() => { // eslint-disable-line react/jsx-no-bind
this.handleShowTTTModal(translatedTile);
}}
{...translatedTile}
/>
);
});
}
render () {
return (
<div>
<div className="banner-wrapper">
<TitleBanner className="masthead ideas-banner">
<div className="title-banner-p">
<img
alt={this.props.intl.formatMessage({id: 'ideas.headerImageDescription'})}
src="/images/ideas/masthead-illustration.svg"
/>
<h1 className="title-banner-h1">
<FormattedMessage id="ideas.headerMessage" />
</h1>
<a href="/projects/editor/?tutorial=all">
<Button className="banner-button">
<img
alt=""
src="/images/ideas/bulb-yellow-icon.svg"
/>
<FormattedMessage id="ideas.headerButtonMessage" />
</Button>
</a>
</div>
</TitleBanner>
</div>
<div className="tips-getting-started">
<div className="inner">
<FlexRow
as="section"
className="tips-info-section tips-left"
>
<div className="ideas-image">
];
const Ideas = () => {
const intl = useIntl();
return (
<div>
<div className="banner-wrapper">
<TitleBanner className="masthead ideas-banner">
<div className="title-banner-p">
<img
alt={intl.formatMessage({id: 'ideas.headerImageDescription'})}
src="/images/ideas/masthead-illustration.svg"
/>
<h1 className="title-banner-h1">
<FormattedMessage id="ideas.headerMessage" />
</h1>
<a href="/projects/editor/?tutorial=all">
<Button className="banner-button">
<img
alt={this.props.intl.formatMessage({id: 'ideas.gettingStartedImageDescription'})}
src="/images/ideas/getting-started-illustration.svg"
alt=""
src="/images/ideas/bulb-yellow-icon.svg"
/>
</div>
<div>
<h2>
<FormattedMessage id="ideas.gettingStartedTitle" />
</h2>
<p>
<FormattedMessage id="ideas.gettingStartedText" />
</p>
<a href="/projects/editor/?tutorial=getStarted">
<Button className="ideas-button">
<img
alt=""
src="/images/ideas/try-it-icon.svg"
/>
<FormattedMessage id="ideas.tryIt" />
</Button>
</a>
</div>
</FlexRow>
<FormattedMessage id="ideas.headerButtonMessage" />
</Button>
</a>
</div>
</div>
<div className="tips-activity-guides">
<div className="inner">
<section className="ttt-section">
<div className="ttt-head">
<h2>
<FormattedMessage id="ideas.activityGuidesTitle" />
</h2>
<p>
<FormattedMessage id="ideas.activityGuidesText" />
</p>
</div>
<MasonryGrid >
{this.renderTiles()}
</MasonryGrid>
<TTTModal
isOpen={this.state.TTTModalOpen}
onRequestClose={this.handleHideTTTModal}
{...this.state.currentTile}
/>
<a
className="wide-button"
href="/projects/editor/?tutorial=all"
>
<Button className="ideas-button wide-button">
<FormattedMessage id="ideas.seeAllTutorials" />
</Button>
</a>
</section>
</div>
</div>
<div>
<div className="inner">
<FlexRow
as="section"
className="tips-info-section cards-info ideas-all-cards"
>
<div className="tips-info-body">
<h2>
<FormattedMessage id="ideas.cardsTitle" />
</h2>
<p>
<FormattedMessage id="ideas.cardsText" />
</p>
<a
href={this.props.intl.formatMessage({
id: 'cards.scratch-cards-allLink'
})}
rel="noopener noreferrer"
target="_blank"
>
<Button className="ideas-button">
<img
alt=""
src="/images/ideas/download-icon.svg"
/>
<FormattedMessage id="general.downloadPDF" />
</Button>
</a>
</div>
<div className="tips-info-body tips-illustration">
<img
alt={this.props.intl.formatMessage({id: 'ideas.cardsIllustrationDescription'})}
src="/images/ideas/cards-illustration.svg"
/>
</div>
</FlexRow>
</div>
</div>
</TitleBanner>
</div>
<div className="tips">
<div className="inner">
<div className="tips-divider" />
</div>
<div>
<div className="inner">
<FlexRow
as="section"
className="ideas-starter tips-info-section tips-left"
>
<div className="ideas-image">
<img
alt={this.props.intl.formatMessage({id: 'ideas.starterProjectsImageDescription'})}
src="/images/ideas/starter-projects-illustration.svg"
/>
</div>
<div className="tips-info-body">
<h2>
<FormattedMessage id="ideas.starterProjectsTitle" />
</h2>
<p>
<FormattedMessage id="ideas.starterProjectsText" />
</p>
<p>
<a href="/starter_projects">
<Button className="ideas-button">
<FormattedMessage id="ideas.starterProjectsButton" />
</Button>
</a>
</p>
</div>
</FlexRow>
<div className="section-header">
<FormattedMessage id="ideas.startHereText" />
</div>
</div>
<div className="gray-area">
<div className="inner">
<FlexRow
as="section"
className="tips-info-section mod-align-top"
>
<div className="tips-info-body mod-narrow">
<FlexRow
as="section"
className="tips-section"
>
{tipsSectionData.map((tipData, index) => (
<div
key={index}
className="tip"
>
<img
className="tips-icon"
alt=""
src="/images/tips/download-icon.svg"
alt={intl.formatMessage({
id: tipData.tipImage.altTextId
})}
src={tipData.tipImage.imageSrc}
className="tips-img"
/>
<h3>
<FormattedMessage id="ideas.desktopEditorHeader" />
</h3>
<p>
<FormattedMessage
id="ideas.desktopEditorBodyHTML"
values={{a: chunks => <a href="/download">{chunks}</a>}}
/>
</p>
<a
href={
tipData.button.href ?
tipData.button.href :
intl.formatMessage({
id: tipData.button.hrefId
})
}
>
<Button className="tips-button">
{tipData.button.buttonImageSrc && (
<img src={tipData.button.buttonImageSrc} />
)}
<FormattedMessage id={tipData.button.buttonTextId} />
</Button>
</a>
</div>
<div className="tips-info-body mod-narrow">
<img
className="tips-icon"
alt=""
src="/images/tips/question-icon.svg"
/>
<h3>
<FormattedMessage id="ideas.questionsHeader" />
</h3>
<p>
<FormattedMessage
id="ideas.questionsBodyHTML"
values={{
faq: chunks => <a href="/info/faq">{chunks}</a>,
forum: chunks => <a href="/discuss/7/">{chunks}</a>
}}
/>
</p>
</div>
</FlexRow>
</div>
))}
</FlexRow>
</div>
</div>
);
}
}
Ideas.propTypes = {
intl: intlShape
<div className="physical-ideas">
<div className="inner">
<div className="section-header">
<FormattedMessage id="ideas.physicalPlayIdeas" />
</div>
<FlexRow
as="section"
className="physical-ideas-section"
>
{physicalIdeasData.map((physicalIdea, index) => (
<div
key={index}
className="physical-idea"
>
<img
src={physicalIdea.physicalIdeasImage.imageSrc}
className={physicalIdea.physicalIdeasImage.imageClass}
/>
<div className="physical-idea-description">
<h3>
<FormattedMessage
id={physicalIdea.physicalIdeasDescription.headerId}
/>
</h3>
<p>
<FormattedMessage
id={physicalIdea.physicalIdeasDescription.bodyId}
/>
</p>
<a
href={intl.formatMessage({
id: physicalIdea.physicalIdeasDescription.hrefId
})}
>
<Button className="tips-button">
<img
src={
physicalIdea.physicalIdeasDescription.buttonImageSrc
}
/>
<FormattedMessage
id={physicalIdea.physicalIdeasDescription.buttonTextId}
/>
</Button>
</a>
</div>
</div>
))}
</FlexRow>
</div>
</div>
<div className="gray-area">
<div className="inner">
<FlexRow
as="section"
className="tips-info-section"
>
<div className="tips-info-body mod-narrow">
<img
className="tips-icon"
alt=""
src="/images/tips/download-icon.svg"
/>
<h3>
<FormattedMessage id="ideas.desktopEditorHeader" />
</h3>
<p>
<FormattedMessage
id="ideas.desktopEditorBodyHTML"
values={{a: chunks => <a href="/download">{chunks}</a>}}
/>
</p>
</div>
<div className="tips-info-body mod-narrow">
<img
className="tips-icon"
alt=""
src="/images/tips/question-icon.svg"
/>
<h3>
<FormattedMessage id="ideas.questionsHeader" />
</h3>
<p>
<FormattedMessage
id="ideas.questionsBodyHTML"
values={{
faq: chunks => <a href="/info/faq">{chunks}</a>,
forum: chunks => <a href="/discuss/7/">{chunks}</a>
}}
/>
</p>
</div>
</FlexRow>
</div>
</div>
</div>
);
};
const WrappedIdeas = injectIntl(Ideas);
render(
<Page><WrappedIdeas /></Page>, document.getElementById('app'));
<Page>
<Ideas />
</Page>,
document.getElementById('app')
);

View file

@ -17,127 +17,131 @@ $base-bg: $ui-white;
background: bottom left url("/images/ideas/left-juice.png") no-repeat;
}
.ttt-section {
.tips {
.inner {
display: flex;
flex-direction: column;
gap: 0.75rem;
.tips-section {
display: flex;
justify-content: space-between;
.tip {
display: flex;
flex-direction: column;
.tips-img {
width: $cols3;
height: 10rem;
}
}
}
}
}
.physical-ideas {
.inner {
display: flex;
flex-direction: column;
gap: 1.5rem;
.physical-ideas-section {
justify-content: space-between;
align-items: flex-start;
gap: 1.5rem;
.physical-idea {
display: flex;
gap: 1.5rem;
text-align: start;
.makey-makey-img {
height: 6.5rem;
}
.micro-bit {
height: 8.5rem;
}
.physical-idea-description {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
p {
margin: 0;
font-size: 1rem;
font-weight: 400;
line-height: 1.5rem;
}
.tips-button {
width: auto;
padding: 0.75rem;
}
}
}
.physical-idea:first-child {
flex: 1.5;
}
.physical-idea:last-child {
flex: 2;
}
}
}
}
.tips, .physical-ideas {
display: flex;
margin: 0 auto;
text-align: center;
justify-content: center;
flex-wrap: wrap;
align-items: center;
}
.tips-divider {
border-top: 1px solid $ui-gray;
width: 100%;
}
.tips-banner-image {
max-width: calc(100% - 2rem);
}
.banner-button {
background-color: $ui-white;
color: $ui-aqua;
font-size: 1rem;
img {
margin-right: 1rem;
height: 1.5rem;
vertical-align: middle;
}
a {
color: $ui-white;
}
span {
vertical-align: middle;
}
}
.ideas-button {
margin-right: .75rem;
background-color: $ui-purple-dark;
color: $ui-white;
font-size: 1rem;
img {
margin-right: 1rem;
height: 1.5rem;
vertical-align: middle;
}
a {
color: $ui-white;
}
span {
vertical-align: middle;
}
}
.wide-button {
width: 100%;
}
.ideas-all-cards {
padding: 5rem 0 !important;
}
.ideas-starter {
padding: 5rem 0 !important;
}
.tips-getting-started {
background-color: $ui-light-gray;
padding-top: 2.5rem;
}
.tips-left {
justify-content: flex-start;
}
.ideas-image {
margin-right: 2rem;
}
.tips-activity-guides {
background-color: $ui-light-gray;
padding-bottom: 2rem;
}
.purchase-button {
img {
margin-right: 0;
margin-left: .75rem;
width: 1rem;
vertical-align: baseline;
}
}
.tips-info-section {
padding: 2.5rem 0;
width: 100%;
flex-wrap: nowrap;
}
.tips-info-body {
text-align: left;
}
.tips-cards-buttons {
a {
white-space: normal;
}
padding: 3rem 0;
background-color: $gray-50;
}
.gray-area {
background-color: $ui-gray;
.tips-info-section {
padding: 2.5rem 0;
width: 100%;
flex-wrap: nowrap;
.tips-info-body {
text-align: left;
}
}
img.tips-icon {
height: 1.75rem;
}
}
img.tips-icon {
height: 1.75rem;
.section-header {
font-size: 2rem;
font-family: "Helvetica Neue", "Helvetica", Arial, sans-serif;
font-weight: 700;
}
.tips-button {
display: flex;
justify-content: center;
align-items: center;
gap: 0.5rem;
font-family: "Helvetica Neue", "Helvetica", Arial, sans-serif;
font-weight: 700;
line-height: 1.25rem;
width: 100%;
padding: 0.5rem 0;
border-radius: 4px;
}
//4 columns
@media #{$small} {
@ -151,14 +155,7 @@ img.tips-icon {
}
}
.ttt-head {
p {
max-width: $cols4;
}
}
//put the image first if in 4-column
// put the image first if in 4-column
.tips-info-body {
max-width: $cols4;
text-align: center;
@ -187,19 +184,6 @@ img.tips-icon {
}
}
.ttt-head {
p {
max-width: $cols6;
}
}
.tips-info-body.tips-illustration {
order: -1;
img {
width: $cols4;
}
}
.tips-info-body {
max-width: $cols4;
text-align: center;
@ -219,23 +203,23 @@ img.tips-icon {
}
}
.ttt-head {
p {
max-width: $cols6;
}
}
.tips-info-section {
&.mod-align-top {
align-items: flex-start;
}
}
.tips-info-body {
max-width: $cols4;
}
}
@media #{$intermediate-and-smaller}{
.physical-ideas {
.inner {
.physical-ideas-section {
.physical-idea:first-child {
flex: 2;
}
}
}
}
}
// 12 columns
@media #{$big} {
.title-banner {
@ -248,12 +232,6 @@ img.tips-icon {
}
}
.ttt-head {
p {
max-width: $cols8;
}
}
.tips-info-section {
&.mod-align-top {
align-items: flex-start;

View file

@ -2,6 +2,8 @@
"cards.scratch-cards-allLink": "https://resources.scratch.mit.edu/www/cards/en/scratch-cards-all.pdf",
"cards.name-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/name-cards.pdf",
"cards.animation-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/animation-cards.pdf",
"cards.microbit-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/microbit-cards.pdf",
"cards.makeymakey-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/makeymakey-cards.pdf",
"cards.music-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/music-cards.pdf",
"cards.story-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/story-cards.pdf",
"cards.chase-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/chase-cards.pdf",

View file

@ -2,12 +2,11 @@
"ideas.headerMessage": "What will you create?",
"ideas.headerImageDescription": "Outlandish creations from pixelated unicorns to drumbeat waveforms to levitating tacos to buckets of rainbows.",
"ideas.headerButtonMessage": "Choose a tutorial",
"ideas.gettingStartedTitle": "Getting Started",
"ideas.gettingStartedText": "New to Scratch? Try the Getting Started tutorial.",
"ideas.startHereText": "New to Scratch? Stay here!",
"ideas.gettingStartedButtonText": "Try Getting Started Tutorial",
"ideas.seeTutorialsLibraryButtonText": "See Tutorials Library",
"ideas.gettingStartedImageDescription": "An illustrated boy plants his flag on top of a freshly painted mountaintop.",
"ideas.tryIt": "Try it!",
"ideas.activityGuidesTitle": "Activity Guides",
"ideas.activityGuidesText": "What do you want to make with Scratch? For each activity, you can try the Tutorial, download a set of Coding Cards, or view the Educator Guide.",
"ideas.seeTutorialsLibraryImageDescription": "An illustration of three tutorial thumbnails.",
"ideas.animateANameTitle": "Animate a Name",
"ideas.animateANameDescription": "Animate the letters of your name, initials, or favorite word.",
"ideas.animateANameImageDescription": "The name ANYA in all caps and blocked letters is poised to wiggle",
@ -26,43 +25,28 @@
"ideas.videoSensingTitle": "Video Sensing",
"ideas.videoSensingDescription": "Interact with a project using the Video Sensing extension.",
"ideas.videoSensingImageDescription": "A virtual hand dodges a spurt of flame in an attempt to pet a dragon.",
"ideas.seeAllTutorials": "See All Tutorials",
"ideas.cardsTitle": "Get the Entire Collection of Coding Cards",
"ideas.cardsText": "With the Scratch Coding Cards, you can learn to create interactive games, stories, music, animations, and more!",
"ideas.cardsIllustrationDescription": "An assortment of fun, animated characters and objects leap out of a stack of cards.",
"ideas.starterProjectsTitle": "Starter Projects",
"ideas.starterProjectsText": "You can play with Starter Projects and remix them to make your own creations.",
"ideas.starterProjectsImageDescription": "An illustration of the Scratch Code Editor.",
"ideas.starterProjectsButton": "Explore Starter Projects",
"ideas.tryTheTutorial": "Try the tutorial",
"ideas.codingCards": "Coding Cards",
"ideas.educatorGuide": "Educator Guide",
"ideas.physicalPlayIdeas": "Physical Play Ideas",
"ideas.microBitHeader": "Have a micro:bit?",
"ideas.microBitBody": "Connect your Scratch project to the real world.",
"ideas.makeyMakeyHeader": "Have a MakeyMakey?",
"ideas.makeyMakeyBody": "Turn anything into a key that connects with your Scratch project!",
"ideas.desktopEditorHeader": "Scratch App Download",
"ideas.desktopEditorBody": "To create projects without an Internet connection, you can <a href=\"/download\">download the Scratch app</a>.",
"ideas.desktopEditorBodyHTML": "To create projects without an Internet connection, you can <a>download the Scratch app</a>.",
"ideas.questionsHeader": "Questions",
"ideas.questionsBody": "Have more questions? See the <a href=\"/info/faq\">Frequently Asked Questions</a> or visit the <a href=\"/discuss/7/\">Help with Scripts Forum</a>.",
"ideas.questionsBodyHTML": "Have more questions? See the <faq>Frequently Asked Questions</faq> or visit the <forum>Help with Scripts Forum</forum>.",
"ideas.cardsPurchase": "Purchase Printed Set",
"ideas.MakeItFlyTitle": "Make It Fly",
"ideas.MakeItFlyDescription": "Choose any character and make it fly!",
"ideas.MakeItFlyImageDescription": "The scratch cat flies over the skyline. Alongside a flying taco.",
"ideas.RaceTitle": "Race to the Finish",
"ideas.RaceDescription": "Make a game where two characters race each other.",
"ideas.HideAndSeekTitle": "Hide and Seek",
"ideas.HideAndSeekDescription": "Make a hide-and-seek game with characters that appear and disappear.",
"ideas.FashionTitle": "Fashion Game",
"ideas.FashionDescription": "Make a game where you dress a character with different clothes and styles.",
"ideas.PongTitle": "Pong Game",
"ideas.PongDescription": "Make a bouncing ball game with sounds, points, and other effects.",
"ideas.PongImageDescription": "A ball bounces off a digital paddle.",
"ideas.ImagineTitle": "Imagine a World",
"ideas.ImagineDescription": "Imagine a world where anything is possible.",
"ideas.ImagineImageDescription": "A girl stands proudly in front of a thought bubble as big as the Earth and as intricate as butterfly wings.",
"ideas.DanceTitle": "Let's Dance",
"ideas.DanceDescription": "Design an animated dance scene with music and dance moves.",
"ideas.CatchTitle": "Catch Game",
"ideas.CatchDescription": "Make a game where you catch things falling from the sky.",
"ideas.VirtualPetTitle": "Virtual Pet",
"ideas.VirtualPetDescription": "Create an interactive pet that can eat, drink, and play."
"ideas.ImagineImageDescription": "A girl stands proudly in front of a thought bubble as big as the Earth and as intricate as butterfly wings."
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB