Emi Matchu
b3f3b39aa0
When you hover the row for a layer in the table, it highlights the corresponding layer in the outfit viewer. And when you click anywhere in the row, it opens the first link (usually the PNG image).
125 lines
3.2 KiB
Sass
125 lines
3.2 KiB
Sass
@import "../partials/clean/constants"
|
|
|
|
// When loading, fade in the loading spinner after a brief delay. We only apply
|
|
// the delay here, not on the base styles, because fading *out* on load should
|
|
// be instant.
|
|
//
|
|
// This is implemented as a mixin, so that the item page can leverage the same
|
|
// loading state when loading a new preview altogether. Once CSS container
|
|
// style queries gain wider support, maybe use that instead.
|
|
=outfit-viewer-loading
|
|
cursor: wait
|
|
|
|
.loading-indicator
|
|
opacity: 1
|
|
transition-delay: 2s
|
|
|
|
// If the outfit *starts* in loading state, still delay the fade-in.
|
|
@starting-style
|
|
opacity: 0
|
|
|
|
outfit-viewer
|
|
display: block
|
|
position: relative
|
|
overflow: hidden
|
|
|
|
// These are default widths, expected to often be overridden.
|
|
width: 300px
|
|
height: 300px
|
|
|
|
// 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
|
|
|
|
.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
|
|
|
|
&:has(outfit-layer:state(loading))
|
|
+outfit-viewer-loading
|
|
|
|
// If a layer has the `[highlighted]` attribute, it's brought to the front,
|
|
// and other layers are grayed out and blurred. We use this in the support
|
|
// outfit viewer, when you hover over a layer.
|
|
&:has(outfit-layer[highlighted])
|
|
outfit-layer[highlighted]
|
|
z-index: 999
|
|
|
|
// Filter everything behind the bottom-most highlighted layer, using a
|
|
// backdrop filter. This gives us the best visual consistency by applying
|
|
// effects to the entire backdrop, instead of each layer and then
|
|
// re-compositing them.
|
|
backdrop-filter: grayscale(1) brightness(1.5) blur(1px)
|
|
& ~ outfit-layer[highlighted]
|
|
backdrop-filter: none
|