forked from OpenNeo/impress
Extract all the item pages' stylesheets into their own CSS files
No more of this loading everything into `application.css`! I'm arbitrarily starting here because that's where I've been playing lately, but this is part of a larger effort to move toward a more straightforward CSS architecture (and away from Sass even?)
This commit is contained in:
parent
38b2bad044
commit
a315282b70
13 changed files with 491 additions and 489 deletions
|
@ -1,30 +0,0 @@
|
||||||
@import "partials/campaign-progress"
|
|
||||||
|
|
||||||
body.items-index, body.items-show, body.items-needed, body.item_trades
|
|
||||||
+campaign-progress
|
|
||||||
|
|
||||||
text-align: center
|
|
||||||
|
|
||||||
.item-search-form
|
|
||||||
display: flex
|
|
||||||
gap: .5em
|
|
||||||
justify-content: center
|
|
||||||
|
|
||||||
input[type=text]
|
|
||||||
font-size: 125%
|
|
||||||
width: 15em
|
|
||||||
flex: 0 1 auto
|
|
||||||
|
|
||||||
h1
|
|
||||||
margin-bottom: 1em
|
|
||||||
img
|
|
||||||
height: 80px
|
|
||||||
margin-bottom: -0.5em
|
|
||||||
width: 80px
|
|
||||||
a
|
|
||||||
text-decoration: none
|
|
||||||
span
|
|
||||||
text-decoration: underline
|
|
||||||
&:hover span
|
|
||||||
text-decoration: none
|
|
||||||
|
|
|
@ -14,10 +14,6 @@
|
||||||
@import closet_lists/form
|
@import closet_lists/form
|
||||||
@import neopets_page_import_tasks/new
|
@import neopets_page_import_tasks/new
|
||||||
@import contributions/index
|
@import contributions/index
|
||||||
@import items
|
|
||||||
@import items/index
|
|
||||||
@import items/show
|
|
||||||
@import item_trades/index
|
|
||||||
@import outfits/index
|
@import outfits/index
|
||||||
@import outfits/new
|
@import outfits/new
|
||||||
@import pets/bulk
|
@import pets/bulk
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
@import "../partials/item_header"
|
|
||||||
|
|
||||||
body.item_trades-index
|
|
||||||
.item-header
|
|
||||||
+item-header
|
|
||||||
|
|
||||||
.item-subpage-title
|
|
||||||
text-align: left
|
|
||||||
margin-bottom: .5em
|
|
||||||
|
|
||||||
.trades-table
|
|
||||||
text-align: left
|
|
||||||
width: 100%
|
|
||||||
table-layout: fixed
|
|
||||||
|
|
||||||
th, td
|
|
||||||
&:nth-child(1), &:nth-child(2)
|
|
||||||
width: 15ch
|
|
||||||
overflow: hidden
|
|
||||||
text-overflow: ellipsis
|
|
||||||
|
|
||||||
.trade-list-names
|
|
||||||
list-style: none
|
|
||||||
|
|
||||||
li
|
|
||||||
display: inline
|
|
||||||
|
|
||||||
&:not(:last-child)::after
|
|
||||||
content: ", "
|
|
28
app/assets/stylesheets/item_trades/index.sass
Normal file
28
app/assets/stylesheets/item_trades/index.sass
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
@import "../partials/item_header"
|
||||||
|
|
||||||
|
.item-header
|
||||||
|
+item-header
|
||||||
|
|
||||||
|
.item-subpage-title
|
||||||
|
text-align: left
|
||||||
|
margin-bottom: .5em
|
||||||
|
|
||||||
|
.trades-table
|
||||||
|
text-align: left
|
||||||
|
width: 100%
|
||||||
|
table-layout: fixed
|
||||||
|
|
||||||
|
th, td
|
||||||
|
&:nth-child(1), &:nth-child(2)
|
||||||
|
width: 15ch
|
||||||
|
overflow: hidden
|
||||||
|
text-overflow: ellipsis
|
||||||
|
|
||||||
|
.trade-list-names
|
||||||
|
list-style: none
|
||||||
|
|
||||||
|
li
|
||||||
|
display: inline
|
||||||
|
|
||||||
|
&:not(:last-child)::after
|
||||||
|
content: ", "
|
|
@ -1,25 +0,0 @@
|
||||||
=main_unit
|
|
||||||
float: left
|
|
||||||
width: 49%
|
|
||||||
h2
|
|
||||||
font-size: 125%
|
|
||||||
|
|
||||||
body.items-index
|
|
||||||
form
|
|
||||||
margin-bottom: 2em
|
|
||||||
|
|
||||||
#search-info
|
|
||||||
+main_unit
|
|
||||||
padding-right: 1%
|
|
||||||
dl
|
|
||||||
text-align: left
|
|
||||||
dd
|
|
||||||
margin-bottom: 1em
|
|
||||||
|
|
||||||
#species-search-links
|
|
||||||
+main_unit
|
|
||||||
padding-left: 1%
|
|
||||||
img
|
|
||||||
height: 80px
|
|
||||||
width: 80px
|
|
||||||
|
|
|
@ -1,401 +0,0 @@
|
||||||
@import "../partials/clean/constants"
|
|
||||||
@import "../partials/clean/mixins"
|
|
||||||
@import "../partials/item_header"
|
|
||||||
|
|
||||||
body.items-show
|
|
||||||
#container
|
|
||||||
width: 900px // A bit more generous to the preview area!
|
|
||||||
|
|
||||||
.item-header
|
|
||||||
+item-header
|
|
||||||
|
|
||||||
#item-contributors
|
|
||||||
+subtle-banner
|
|
||||||
clear: both
|
|
||||||
margin:
|
|
||||||
bottom: 0
|
|
||||||
top: 2em
|
|
||||||
|
|
||||||
header
|
|
||||||
display: inline
|
|
||||||
font-weight: bold
|
|
||||||
margin-right: .25em
|
|
||||||
|
|
||||||
footer
|
|
||||||
display: inline
|
|
||||||
|
|
||||||
ul
|
|
||||||
display: inline
|
|
||||||
list-style: none
|
|
||||||
|
|
||||||
li
|
|
||||||
display: inline
|
|
||||||
|
|
||||||
&::after
|
|
||||||
content: ", "
|
|
||||||
|
|
||||||
&:last-child::after
|
|
||||||
content: "."
|
|
||||||
|
|
||||||
.nc-icon
|
|
||||||
height: 16px
|
|
||||||
width: 16px
|
|
||||||
|
|
||||||
.preview-area
|
|
||||||
margin: 0 auto
|
|
||||||
position: relative
|
|
||||||
|
|
||||||
.customize-more
|
|
||||||
position: absolute
|
|
||||||
top: 1em
|
|
||||||
right: 1em
|
|
||||||
|
|
||||||
display: flex
|
|
||||||
align-items: center
|
|
||||||
text-decoration: none
|
|
||||||
|
|
||||||
background: #EDF2F7
|
|
||||||
padding-inline: .75em
|
|
||||||
border-radius: .375em
|
|
||||||
min-height: 2rem
|
|
||||||
min-width: 2rem
|
|
||||||
box-sizing: border-box
|
|
||||||
|
|
||||||
.customize-more-label
|
|
||||||
width: 0
|
|
||||||
overflow: hidden
|
|
||||||
transition: width .25s
|
|
||||||
white-space: nowrap
|
|
||||||
--natural-width: auto
|
|
||||||
|
|
||||||
measured-content
|
|
||||||
padding-right: .5em
|
|
||||||
|
|
||||||
&:hover, &:focus
|
|
||||||
// Expand the label to its natural width. If the JS ran to tell us
|
|
||||||
// what it is in px, we can use that for a smooth transition. If not,
|
|
||||||
// okay, we just pop out to `auto`, which CSS can't make smooth.
|
|
||||||
.customize-more-label
|
|
||||||
width: var(--natural-width)
|
|
||||||
|
|
||||||
outfit-viewer
|
|
||||||
display: block
|
|
||||||
position: relative
|
|
||||||
width: 300px
|
|
||||||
height: 300px
|
|
||||||
border: 1px solid $module-border-color
|
|
||||||
border-radius: 1em
|
|
||||||
overflow: hidden
|
|
||||||
|
|
||||||
// There's no useful text in here, but double-clicking the play/pause
|
|
||||||
// button can cause a weird selection state. Disable text selection.
|
|
||||||
user-select: none
|
|
||||||
-webkit-user-select: none
|
|
||||||
|
|
||||||
outfit-layer
|
|
||||||
display: block
|
|
||||||
position: absolute
|
|
||||||
inset: 0
|
|
||||||
|
|
||||||
// We disable pointer-events most importantly for the iframes, which
|
|
||||||
// will ignore our `cursor: wait` and show a plain cursor for the
|
|
||||||
// inside of its own document. But also, the context menus for these
|
|
||||||
// elements are kinda actively misleading, too!
|
|
||||||
pointer-events: none
|
|
||||||
|
|
||||||
img, iframe
|
|
||||||
width: 100%
|
|
||||||
height: 100%
|
|
||||||
|
|
||||||
.loading-indicator
|
|
||||||
position: absolute
|
|
||||||
z-index: 1000
|
|
||||||
bottom: 0px
|
|
||||||
right: 4px
|
|
||||||
padding: 8px
|
|
||||||
background: radial-gradient(circle closest-side, white 45%, #ffffff00)
|
|
||||||
|
|
||||||
opacity: 0
|
|
||||||
transition: opacity .5s
|
|
||||||
|
|
||||||
.play-pause-button
|
|
||||||
position: absolute
|
|
||||||
z-index: 1001
|
|
||||||
left: 8px
|
|
||||||
bottom: 8px
|
|
||||||
display: none
|
|
||||||
align-items: center
|
|
||||||
justify-content: center
|
|
||||||
color: white
|
|
||||||
background: rgba(0, 0, 0, 0.64)
|
|
||||||
width: 2.5em
|
|
||||||
height: 2.5em
|
|
||||||
border-radius: 100%
|
|
||||||
border: 2px solid transparent
|
|
||||||
transition: all .25s
|
|
||||||
|
|
||||||
.playing-label, .paused-label
|
|
||||||
display: none
|
|
||||||
width: 1em
|
|
||||||
height: 1em
|
|
||||||
|
|
||||||
.play-pause-toggle
|
|
||||||
// Visually hidden
|
|
||||||
clip: rect(0 0 0 0)
|
|
||||||
clip-path: inset(50%)
|
|
||||||
height: 1px
|
|
||||||
overflow: hidden
|
|
||||||
position: absolute
|
|
||||||
white-space: nowrap
|
|
||||||
width: 1px
|
|
||||||
|
|
||||||
&:checked ~ .playing-label
|
|
||||||
display: block
|
|
||||||
|
|
||||||
&:not(:checked) ~ .paused-label
|
|
||||||
display: block
|
|
||||||
|
|
||||||
&:hover, &:has(.play-pause-toggle:focus)
|
|
||||||
border: 2px solid $module-border-color
|
|
||||||
background: $module-bg-color
|
|
||||||
color: $text-color
|
|
||||||
|
|
||||||
&:has(.play-pause-toggle:active)
|
|
||||||
transform: translateY(2px)
|
|
||||||
|
|
||||||
&:has(outfit-layer:state(has-animations))
|
|
||||||
.play-pause-button
|
|
||||||
display: flex
|
|
||||||
|
|
||||||
.error-indicator
|
|
||||||
font-size: 85%
|
|
||||||
color: $error-color
|
|
||||||
margin-top: .25em
|
|
||||||
margin-bottom: .5em
|
|
||||||
display: none
|
|
||||||
|
|
||||||
// When loading, fade in the loading spinner after a brief delay. We are
|
|
||||||
// loading when the <turbo-frame> is busy, or when at least one layer
|
|
||||||
// is loading.
|
|
||||||
//
|
|
||||||
// We only apply the delay here, not on the base styles, because fading
|
|
||||||
// *out* on load should be instant. We also wait for the outfit-viewer to
|
|
||||||
// execute a `setTimeout(0)`, to make sure we always *start* in the
|
|
||||||
// non-loading state. This is because it's sometimes possible for the page to
|
|
||||||
// start with the web component already in `state(loading)`, and we need to
|
|
||||||
// make sure we *start* in *non-loading* state for the transition delay to
|
|
||||||
// happen. (This can happen when you Turbo-navigate between multiple items.)
|
|
||||||
#item-preview[busy] outfit-viewer, outfit-viewer:has(outfit-layer:state(loading))
|
|
||||||
cursor: wait
|
|
||||||
|
|
||||||
&:state(after-first-frame)
|
|
||||||
.loading-indicator
|
|
||||||
opacity: 1
|
|
||||||
transition-delay: 2s
|
|
||||||
|
|
||||||
#item-preview:has(outfit-layer:state(error))
|
|
||||||
outfit-viewer
|
|
||||||
border: 2px solid red
|
|
||||||
.error-indicator
|
|
||||||
display: block
|
|
||||||
|
|
||||||
species-color-picker
|
|
||||||
.error-icon
|
|
||||||
cursor: help
|
|
||||||
margin-right: .25em
|
|
||||||
|
|
||||||
form[data-is-valid="false"]
|
|
||||||
select
|
|
||||||
border-color: $error-border-color
|
|
||||||
color: $error-color
|
|
||||||
|
|
||||||
// If JS is enabled, but auto-loading isn't ready yet (script loading or
|
|
||||||
// failed?), hide the submit button for .75sec, to give it time to load.
|
|
||||||
@media (scripting: enabled)
|
|
||||||
input[type=submit]
|
|
||||||
position: absolute
|
|
||||||
margin-left: .5em
|
|
||||||
opacity: 0
|
|
||||||
animation: fade-in .25s forwards
|
|
||||||
animation-delay: .75s
|
|
||||||
|
|
||||||
// Once the auto-loading behavior is ready, remove the submit button.
|
|
||||||
&:state(auto-loading)
|
|
||||||
input[type=submit]
|
|
||||||
display: none
|
|
||||||
|
|
||||||
species-face-picker
|
|
||||||
display: block
|
|
||||||
position: relative
|
|
||||||
margin-top: -10px
|
|
||||||
|
|
||||||
species-face-picker-options
|
|
||||||
display: flex
|
|
||||||
justify-content: center
|
|
||||||
flex-wrap: wrap
|
|
||||||
isolation: isolate // avoid z-index conflicts between pets and noscript
|
|
||||||
overflow: auto
|
|
||||||
max-height: 200px // 4 rows of 50px images, and padding will offer a hint of below
|
|
||||||
padding: 10px // leave enough room for the zoomed-in selected face
|
|
||||||
|
|
||||||
img
|
|
||||||
width: 54px
|
|
||||||
height: 54px
|
|
||||||
transition: all 0.2s
|
|
||||||
|
|
||||||
// Calm down the default color, just a smidge! There's a lot of color
|
|
||||||
// on this page already, y'know?
|
|
||||||
opacity: .9
|
|
||||||
filter: saturate(90%)
|
|
||||||
|
|
||||||
label
|
|
||||||
display: flex
|
|
||||||
overflow: hidden
|
|
||||||
transition: all 0.2s
|
|
||||||
position: relative
|
|
||||||
line-height: 1
|
|
||||||
|
|
||||||
// NOTE: The box-shadows here were copy-pasted from Impress 2020, which uses
|
|
||||||
// Chakra UI's styling system to generate them! (The colors are from their
|
|
||||||
// color palette, too.)
|
|
||||||
&:has(input:checked)
|
|
||||||
border-radius: 6px
|
|
||||||
z-index: 1
|
|
||||||
background: #9AE6B4
|
|
||||||
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),0 10px 10px -5px rgba(0, 0, 0, 0.04), #2F855A 0 0 2px 2px
|
|
||||||
transform: scale(1.1)
|
|
||||||
|
|
||||||
&:has(input:focus)
|
|
||||||
background: #BEE3F8
|
|
||||||
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),0 10px 10px -5px rgba(0, 0, 0, 0.04), #4299e1 0 0 0 3px
|
|
||||||
transform: scale(1.2)
|
|
||||||
|
|
||||||
input[type=radio]
|
|
||||||
position: absolute
|
|
||||||
left: -10000px
|
|
||||||
top: auto
|
|
||||||
width: 1px
|
|
||||||
height: 1px
|
|
||||||
overflow: hidden
|
|
||||||
|
|
||||||
&:checked + img
|
|
||||||
opacity: 1
|
|
||||||
filter: saturate(110%)
|
|
||||||
|
|
||||||
&:disabled + img
|
|
||||||
opacity: .6
|
|
||||||
filter: saturate(0%)
|
|
||||||
|
|
||||||
label:has(input[type=radio]:disabled)
|
|
||||||
cursor: not-allowed
|
|
||||||
|
|
||||||
noscript
|
|
||||||
position: absolute
|
|
||||||
inset: 0
|
|
||||||
padding: 1em
|
|
||||||
background: rgba(white, .8)
|
|
||||||
z-index: 1
|
|
||||||
cursor: auto
|
|
||||||
|
|
||||||
display: flex
|
|
||||||
align-items: center
|
|
||||||
justify-content: center
|
|
||||||
text-align: center
|
|
||||||
|
|
||||||
&:has(species-face-picker-options[inert])
|
|
||||||
cursor: wait
|
|
||||||
|
|
||||||
.item-preview-meta-info
|
|
||||||
display: grid
|
|
||||||
grid-template-columns: 1fr auto
|
|
||||||
gap: .5em
|
|
||||||
align-items: center
|
|
||||||
|
|
||||||
.item-zones-info
|
|
||||||
h3
|
|
||||||
display: inline
|
|
||||||
font: inherit
|
|
||||||
font-weight: bold
|
|
||||||
&:after
|
|
||||||
content: ": "
|
|
||||||
|
|
||||||
ul
|
|
||||||
list-style-type: none
|
|
||||||
display: inline
|
|
||||||
|
|
||||||
li
|
|
||||||
display: inline
|
|
||||||
&:not(:last-of-type):after
|
|
||||||
content: ", "
|
|
||||||
|
|
||||||
.no-zones
|
|
||||||
font-style: italic
|
|
||||||
opacity: .85
|
|
||||||
|
|
||||||
.zone-species-info
|
|
||||||
font-style: italic
|
|
||||||
text-decoration: underline dotted
|
|
||||||
|
|
||||||
// Many of these styles copied from Impress 2020 and its Chakra UI styles!
|
|
||||||
.item-html5-info
|
|
||||||
display: flex
|
|
||||||
align-items: center
|
|
||||||
border: 1px solid
|
|
||||||
border-radius: .375em
|
|
||||||
padding: 4px 8px
|
|
||||||
min-height: 30px
|
|
||||||
box-sizing: border-box
|
|
||||||
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px
|
|
||||||
|
|
||||||
&[data-status=converted]
|
|
||||||
background: $module-bg-color
|
|
||||||
color: $text-color
|
|
||||||
|
|
||||||
svg:nth-of-type(2)
|
|
||||||
margin-right: -4px // spacing hacks!
|
|
||||||
|
|
||||||
&[data-status=unconverted]
|
|
||||||
background: $warning-bg-color
|
|
||||||
color: #975A16
|
|
||||||
gap: .25em // spacing hacks!
|
|
||||||
|
|
||||||
svg:first-of-type
|
|
||||||
width: 12px
|
|
||||||
height: 12px
|
|
||||||
|
|
||||||
svg:nth-of-type(2)
|
|
||||||
width: 20px
|
|
||||||
height: 20px
|
|
||||||
|
|
||||||
#item-preview
|
|
||||||
display: flex
|
|
||||||
flex-direction: column
|
|
||||||
gap: .75em
|
|
||||||
|
|
||||||
@media (min-width: 700px)
|
|
||||||
display: grid
|
|
||||||
grid-template-areas: "viewer faces" "picker meta"
|
|
||||||
gap: .5em
|
|
||||||
|
|
||||||
.preview-area
|
|
||||||
grid-area: viewer
|
|
||||||
outfit-viewer
|
|
||||||
width: 380px
|
|
||||||
height: 380px
|
|
||||||
|
|
||||||
species-color-picker
|
|
||||||
grid-area: picker
|
|
||||||
|
|
||||||
species-face-picker
|
|
||||||
grid-area: faces
|
|
||||||
species-face-picker-options
|
|
||||||
max-height: 380px
|
|
||||||
|
|
||||||
.item-preview-meta-info
|
|
||||||
grid-area: meta
|
|
||||||
|
|
||||||
@keyframes fade-in
|
|
||||||
from
|
|
||||||
opacity: 0
|
|
||||||
to
|
|
||||||
opacity: 1
|
|
23
app/assets/stylesheets/items/index.sass
Normal file
23
app/assets/stylesheets/items/index.sass
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
=main_unit
|
||||||
|
float: left
|
||||||
|
width: 49%
|
||||||
|
h2
|
||||||
|
font-size: 125%
|
||||||
|
|
||||||
|
form
|
||||||
|
margin-bottom: 2em
|
||||||
|
|
||||||
|
#search-info
|
||||||
|
+main_unit
|
||||||
|
padding-right: 1%
|
||||||
|
dl
|
||||||
|
text-align: left
|
||||||
|
dd
|
||||||
|
margin-bottom: 1em
|
||||||
|
|
||||||
|
#species-search-links
|
||||||
|
+main_unit
|
||||||
|
padding-left: 1%
|
||||||
|
img
|
||||||
|
height: 80px
|
||||||
|
width: 80px
|
400
app/assets/stylesheets/items/show.sass
Normal file
400
app/assets/stylesheets/items/show.sass
Normal file
|
@ -0,0 +1,400 @@
|
||||||
|
@import "../partials/clean/constants"
|
||||||
|
@import "../partials/clean/mixins"
|
||||||
|
@import "../partials/item_header"
|
||||||
|
|
||||||
|
#container
|
||||||
|
width: 900px // A bit more generous to the preview area!
|
||||||
|
|
||||||
|
.item-header
|
||||||
|
+item-header
|
||||||
|
|
||||||
|
#item-contributors
|
||||||
|
+subtle-banner
|
||||||
|
clear: both
|
||||||
|
margin:
|
||||||
|
bottom: 0
|
||||||
|
top: 2em
|
||||||
|
|
||||||
|
header
|
||||||
|
display: inline
|
||||||
|
font-weight: bold
|
||||||
|
margin-right: .25em
|
||||||
|
|
||||||
|
footer
|
||||||
|
display: inline
|
||||||
|
|
||||||
|
ul
|
||||||
|
display: inline
|
||||||
|
list-style: none
|
||||||
|
|
||||||
|
li
|
||||||
|
display: inline
|
||||||
|
|
||||||
|
&::after
|
||||||
|
content: ", "
|
||||||
|
|
||||||
|
&:last-child::after
|
||||||
|
content: "."
|
||||||
|
|
||||||
|
.nc-icon
|
||||||
|
height: 16px
|
||||||
|
width: 16px
|
||||||
|
|
||||||
|
.preview-area
|
||||||
|
margin: 0 auto
|
||||||
|
position: relative
|
||||||
|
|
||||||
|
.customize-more
|
||||||
|
position: absolute
|
||||||
|
top: 1em
|
||||||
|
right: 1em
|
||||||
|
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
text-decoration: none
|
||||||
|
|
||||||
|
background: #EDF2F7
|
||||||
|
padding-inline: .75em
|
||||||
|
border-radius: .375em
|
||||||
|
min-height: 2rem
|
||||||
|
min-width: 2rem
|
||||||
|
box-sizing: border-box
|
||||||
|
|
||||||
|
.customize-more-label
|
||||||
|
width: 0
|
||||||
|
overflow: hidden
|
||||||
|
transition: width .25s
|
||||||
|
white-space: nowrap
|
||||||
|
--natural-width: auto
|
||||||
|
|
||||||
|
measured-content
|
||||||
|
padding-right: .5em
|
||||||
|
|
||||||
|
&:hover, &:focus
|
||||||
|
// Expand the label to its natural width. If the JS ran to tell us
|
||||||
|
// what it is in px, we can use that for a smooth transition. If not,
|
||||||
|
// okay, we just pop out to `auto`, which CSS can't make smooth.
|
||||||
|
.customize-more-label
|
||||||
|
width: var(--natural-width)
|
||||||
|
|
||||||
|
outfit-viewer
|
||||||
|
display: block
|
||||||
|
position: relative
|
||||||
|
width: 300px
|
||||||
|
height: 300px
|
||||||
|
border: 1px solid $module-border-color
|
||||||
|
border-radius: 1em
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
// There's no useful text in here, but double-clicking the play/pause
|
||||||
|
// button can cause a weird selection state. Disable text selection.
|
||||||
|
user-select: none
|
||||||
|
-webkit-user-select: none
|
||||||
|
|
||||||
|
outfit-layer
|
||||||
|
display: block
|
||||||
|
position: absolute
|
||||||
|
inset: 0
|
||||||
|
|
||||||
|
// We disable pointer-events most importantly for the iframes, which
|
||||||
|
// will ignore our `cursor: wait` and show a plain cursor for the
|
||||||
|
// inside of its own document. But also, the context menus for these
|
||||||
|
// elements are kinda actively misleading, too!
|
||||||
|
pointer-events: none
|
||||||
|
|
||||||
|
img, iframe
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
|
||||||
|
.loading-indicator
|
||||||
|
position: absolute
|
||||||
|
z-index: 1000
|
||||||
|
bottom: 0px
|
||||||
|
right: 4px
|
||||||
|
padding: 8px
|
||||||
|
background: radial-gradient(circle closest-side, white 45%, #ffffff00)
|
||||||
|
|
||||||
|
opacity: 0
|
||||||
|
transition: opacity .5s
|
||||||
|
|
||||||
|
.play-pause-button
|
||||||
|
position: absolute
|
||||||
|
z-index: 1001
|
||||||
|
left: 8px
|
||||||
|
bottom: 8px
|
||||||
|
display: none
|
||||||
|
align-items: center
|
||||||
|
justify-content: center
|
||||||
|
color: white
|
||||||
|
background: rgba(0, 0, 0, 0.64)
|
||||||
|
width: 2.5em
|
||||||
|
height: 2.5em
|
||||||
|
border-radius: 100%
|
||||||
|
border: 2px solid transparent
|
||||||
|
transition: all .25s
|
||||||
|
|
||||||
|
.playing-label, .paused-label
|
||||||
|
display: none
|
||||||
|
width: 1em
|
||||||
|
height: 1em
|
||||||
|
|
||||||
|
.play-pause-toggle
|
||||||
|
// Visually hidden
|
||||||
|
clip: rect(0 0 0 0)
|
||||||
|
clip-path: inset(50%)
|
||||||
|
height: 1px
|
||||||
|
overflow: hidden
|
||||||
|
position: absolute
|
||||||
|
white-space: nowrap
|
||||||
|
width: 1px
|
||||||
|
|
||||||
|
&:checked ~ .playing-label
|
||||||
|
display: block
|
||||||
|
|
||||||
|
&:not(:checked) ~ .paused-label
|
||||||
|
display: block
|
||||||
|
|
||||||
|
&:hover, &:has(.play-pause-toggle:focus)
|
||||||
|
border: 2px solid $module-border-color
|
||||||
|
background: $module-bg-color
|
||||||
|
color: $text-color
|
||||||
|
|
||||||
|
&:has(.play-pause-toggle:active)
|
||||||
|
transform: translateY(2px)
|
||||||
|
|
||||||
|
&:has(outfit-layer:state(has-animations))
|
||||||
|
.play-pause-button
|
||||||
|
display: flex
|
||||||
|
|
||||||
|
.error-indicator
|
||||||
|
font-size: 85%
|
||||||
|
color: $error-color
|
||||||
|
margin-top: .25em
|
||||||
|
margin-bottom: .5em
|
||||||
|
display: none
|
||||||
|
|
||||||
|
// When loading, fade in the loading spinner after a brief delay. We are
|
||||||
|
// loading when the <turbo-frame> is busy, or when at least one layer
|
||||||
|
// is loading.
|
||||||
|
//
|
||||||
|
// We only apply the delay here, not on the base styles, because fading
|
||||||
|
// *out* on load should be instant. We also wait for the outfit-viewer to
|
||||||
|
// execute a `setTimeout(0)`, to make sure we always *start* in the
|
||||||
|
// non-loading state. This is because it's sometimes possible for the page to
|
||||||
|
// start with the web component already in `state(loading)`, and we need to
|
||||||
|
// make sure we *start* in *non-loading* state for the transition delay to
|
||||||
|
// happen. (This can happen when you Turbo-navigate between multiple items.)
|
||||||
|
#item-preview[busy] outfit-viewer, outfit-viewer:has(outfit-layer:state(loading))
|
||||||
|
cursor: wait
|
||||||
|
|
||||||
|
&:state(after-first-frame)
|
||||||
|
.loading-indicator
|
||||||
|
opacity: 1
|
||||||
|
transition-delay: 2s
|
||||||
|
|
||||||
|
#item-preview:has(outfit-layer:state(error))
|
||||||
|
outfit-viewer
|
||||||
|
border: 2px solid red
|
||||||
|
.error-indicator
|
||||||
|
display: block
|
||||||
|
|
||||||
|
species-color-picker
|
||||||
|
.error-icon
|
||||||
|
cursor: help
|
||||||
|
margin-right: .25em
|
||||||
|
|
||||||
|
form[data-is-valid="false"]
|
||||||
|
select
|
||||||
|
border-color: $error-border-color
|
||||||
|
color: $error-color
|
||||||
|
|
||||||
|
// If JS is enabled, but auto-loading isn't ready yet (script loading or
|
||||||
|
// failed?), hide the submit button for .75sec, to give it time to load.
|
||||||
|
@media (scripting: enabled)
|
||||||
|
input[type=submit]
|
||||||
|
position: absolute
|
||||||
|
margin-left: .5em
|
||||||
|
opacity: 0
|
||||||
|
animation: fade-in .25s forwards
|
||||||
|
animation-delay: .75s
|
||||||
|
|
||||||
|
// Once the auto-loading behavior is ready, remove the submit button.
|
||||||
|
&:state(auto-loading)
|
||||||
|
input[type=submit]
|
||||||
|
display: none
|
||||||
|
|
||||||
|
species-face-picker
|
||||||
|
display: block
|
||||||
|
position: relative
|
||||||
|
margin-top: -10px
|
||||||
|
|
||||||
|
species-face-picker-options
|
||||||
|
display: flex
|
||||||
|
justify-content: center
|
||||||
|
flex-wrap: wrap
|
||||||
|
isolation: isolate // avoid z-index conflicts between pets and noscript
|
||||||
|
overflow: auto
|
||||||
|
max-height: 200px // 4 rows of 50px images, and padding will offer a hint of below
|
||||||
|
padding: 10px // leave enough room for the zoomed-in selected face
|
||||||
|
|
||||||
|
img
|
||||||
|
width: 54px
|
||||||
|
height: 54px
|
||||||
|
transition: all 0.2s
|
||||||
|
|
||||||
|
// Calm down the default color, just a smidge! There's a lot of color
|
||||||
|
// on this page already, y'know?
|
||||||
|
opacity: .9
|
||||||
|
filter: saturate(90%)
|
||||||
|
|
||||||
|
label
|
||||||
|
display: flex
|
||||||
|
overflow: hidden
|
||||||
|
transition: all 0.2s
|
||||||
|
position: relative
|
||||||
|
line-height: 1
|
||||||
|
|
||||||
|
// NOTE: The box-shadows here were copy-pasted from Impress 2020, which uses
|
||||||
|
// Chakra UI's styling system to generate them! (The colors are from their
|
||||||
|
// color palette, too.)
|
||||||
|
&:has(input:checked)
|
||||||
|
border-radius: 6px
|
||||||
|
z-index: 1
|
||||||
|
background: #9AE6B4
|
||||||
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),0 10px 10px -5px rgba(0, 0, 0, 0.04), #2F855A 0 0 2px 2px
|
||||||
|
transform: scale(1.1)
|
||||||
|
|
||||||
|
&:has(input:focus)
|
||||||
|
background: #BEE3F8
|
||||||
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),0 10px 10px -5px rgba(0, 0, 0, 0.04), #4299e1 0 0 0 3px
|
||||||
|
transform: scale(1.2)
|
||||||
|
|
||||||
|
input[type=radio]
|
||||||
|
position: absolute
|
||||||
|
left: -10000px
|
||||||
|
top: auto
|
||||||
|
width: 1px
|
||||||
|
height: 1px
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
&:checked + img
|
||||||
|
opacity: 1
|
||||||
|
filter: saturate(110%)
|
||||||
|
|
||||||
|
&:disabled + img
|
||||||
|
opacity: .6
|
||||||
|
filter: saturate(0%)
|
||||||
|
|
||||||
|
label:has(input[type=radio]:disabled)
|
||||||
|
cursor: not-allowed
|
||||||
|
|
||||||
|
noscript
|
||||||
|
position: absolute
|
||||||
|
inset: 0
|
||||||
|
padding: 1em
|
||||||
|
background: rgba(white, .8)
|
||||||
|
z-index: 1
|
||||||
|
cursor: auto
|
||||||
|
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
justify-content: center
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
&:has(species-face-picker-options[inert])
|
||||||
|
cursor: wait
|
||||||
|
|
||||||
|
.item-preview-meta-info
|
||||||
|
display: grid
|
||||||
|
grid-template-columns: 1fr auto
|
||||||
|
gap: .5em
|
||||||
|
align-items: center
|
||||||
|
|
||||||
|
.item-zones-info
|
||||||
|
h3
|
||||||
|
display: inline
|
||||||
|
font: inherit
|
||||||
|
font-weight: bold
|
||||||
|
&:after
|
||||||
|
content: ": "
|
||||||
|
|
||||||
|
ul
|
||||||
|
list-style-type: none
|
||||||
|
display: inline
|
||||||
|
|
||||||
|
li
|
||||||
|
display: inline
|
||||||
|
&:not(:last-of-type):after
|
||||||
|
content: ", "
|
||||||
|
|
||||||
|
.no-zones
|
||||||
|
font-style: italic
|
||||||
|
opacity: .85
|
||||||
|
|
||||||
|
.zone-species-info
|
||||||
|
font-style: italic
|
||||||
|
text-decoration: underline dotted
|
||||||
|
|
||||||
|
// Many of these styles copied from Impress 2020 and its Chakra UI styles!
|
||||||
|
.item-html5-info
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
border: 1px solid
|
||||||
|
border-radius: .375em
|
||||||
|
padding: 4px 8px
|
||||||
|
min-height: 30px
|
||||||
|
box-sizing: border-box
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px
|
||||||
|
|
||||||
|
&[data-status=converted]
|
||||||
|
background: $module-bg-color
|
||||||
|
color: $text-color
|
||||||
|
|
||||||
|
svg:nth-of-type(2)
|
||||||
|
margin-right: -4px // spacing hacks!
|
||||||
|
|
||||||
|
&[data-status=unconverted]
|
||||||
|
background: $warning-bg-color
|
||||||
|
color: #975A16
|
||||||
|
gap: .25em // spacing hacks!
|
||||||
|
|
||||||
|
svg:first-of-type
|
||||||
|
width: 12px
|
||||||
|
height: 12px
|
||||||
|
|
||||||
|
svg:nth-of-type(2)
|
||||||
|
width: 20px
|
||||||
|
height: 20px
|
||||||
|
|
||||||
|
#item-preview
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
gap: .75em
|
||||||
|
|
||||||
|
@media (min-width: 700px)
|
||||||
|
display: grid
|
||||||
|
grid-template-areas: "viewer faces" "picker meta"
|
||||||
|
gap: .5em
|
||||||
|
|
||||||
|
.preview-area
|
||||||
|
grid-area: viewer
|
||||||
|
outfit-viewer
|
||||||
|
width: 380px
|
||||||
|
height: 380px
|
||||||
|
|
||||||
|
species-color-picker
|
||||||
|
grid-area: picker
|
||||||
|
|
||||||
|
species-face-picker
|
||||||
|
grid-area: faces
|
||||||
|
species-face-picker-options
|
||||||
|
max-height: 380px
|
||||||
|
|
||||||
|
.item-preview-meta-info
|
||||||
|
grid-area: meta
|
||||||
|
|
||||||
|
@keyframes fade-in
|
||||||
|
from
|
||||||
|
opacity: 0
|
||||||
|
to
|
||||||
|
opacity: 1
|
28
app/assets/stylesheets/layouts/items.sass
Normal file
28
app/assets/stylesheets/layouts/items.sass
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
@import "partials/campaign-progress"
|
||||||
|
|
||||||
|
body
|
||||||
|
+campaign-progress
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
.item-search-form
|
||||||
|
display: flex
|
||||||
|
gap: .5em
|
||||||
|
justify-content: center
|
||||||
|
|
||||||
|
input[type=text]
|
||||||
|
font-size: 125%
|
||||||
|
width: 15em
|
||||||
|
flex: 0 1 auto
|
||||||
|
|
||||||
|
h1
|
||||||
|
margin-bottom: 1em
|
||||||
|
img
|
||||||
|
height: 80px
|
||||||
|
margin-bottom: -0.5em
|
||||||
|
width: 80px
|
||||||
|
a
|
||||||
|
text-decoration: none
|
||||||
|
span
|
||||||
|
text-decoration: underline
|
||||||
|
&:hover span
|
||||||
|
text-decoration: none
|
|
@ -34,3 +34,7 @@
|
||||||
class: "not-in-a-list"
|
class: "not-in-a-list"
|
||||||
- else
|
- else
|
||||||
%p= t(".no_trades_yet")
|
%p= t(".no_trades_yet")
|
||||||
|
|
||||||
|
- content_for :stylesheets do
|
||||||
|
= page_stylesheet_link_tag "layouts/items"
|
||||||
|
= page_stylesheet_link_tag "item_trades/index"
|
||||||
|
|
|
@ -37,3 +37,6 @@
|
||||||
%h2= t '.species_search.header'
|
%h2= t '.species_search.header'
|
||||||
= standard_species_search_links
|
= standard_species_search_links
|
||||||
|
|
||||||
|
- content_for :stylesheets do
|
||||||
|
= page_stylesheet_link_tag "layouts/items"
|
||||||
|
= page_stylesheet_link_tag "items/index"
|
||||||
|
|
|
@ -14,3 +14,6 @@
|
||||||
= link_to 'What do I own?', 'https://www.neopets.com/closet.phtml',
|
= link_to 'What do I own?', 'https://www.neopets.com/closet.phtml',
|
||||||
:class => 'button', :target => '_blank'
|
:class => 'button', :target => '_blank'
|
||||||
= render @items
|
= render @items
|
||||||
|
|
||||||
|
- content_for :stylesheets do
|
||||||
|
= page_stylesheet_link_tag "layouts/items"
|
||||||
|
|
|
@ -122,6 +122,8 @@
|
||||||
|
|
||||||
- content_for :stylesheets do
|
- content_for :stylesheets do
|
||||||
= stylesheet_link_tag "application/hanger-spinner"
|
= stylesheet_link_tag "application/hanger-spinner"
|
||||||
|
= page_stylesheet_link_tag "layouts/items"
|
||||||
|
= page_stylesheet_link_tag "items/show"
|
||||||
|
|
||||||
- content_for :javascripts do
|
- content_for :javascripts do
|
||||||
= javascript_include_tag "lib/idiomorph", async: true
|
= javascript_include_tag "lib/idiomorph", async: true
|
||||||
|
|
Loading…
Reference in a new issue