summaryrefslogtreecommitdiffhomepage
path: root/assets/ext-stage-dock/dock.rcss
blob: 942a820f1cc1875f3fede2cf6d37c29464c85a73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* body.dock is the STATIONARY full-surface DRAG HANDLE — it carries `drag: drag`
   (so RmlUi emits dragstart/drag/dragend that our bind_drag reads) but it is
   NEVER transformed. This is load-bearing: RmlUi projects a drag event's
   mouse_x/mouse_y into the DRAGGED element's transformed coordinate frame, so if
   the dragged element itself were translated by `slide` (as it was), the reported
   drag x would feed back into `slide` and ping-pong between the finger position
   and ~dock_width every frame (the flicker). Keeping the drag handle at identity
   transform makes the reported coordinate the raw finger position. The MOVING
   visual is div.panel below — a child that is NOT the drag element, so its
   transform never enters the drag projection. body itself paints nothing (the
   gradient lives on the panel); it is just the input-capture + drag-origin layer. */
body.dock {
    width: 100%;
    height: 100%;
    drag: drag;
}
/* div.panel is the VALUE-DRIVEN moving visual: data-style-transform binds
   translateX(slide px) (closed = -dock_width, open = 0). The gradient, padding,
   flex layout and scroll live here, not on body. */
div.panel {
    width: 100%;
    height: 100%;
    /* Use the SHADER-based linear-gradient (not the legacy horizontal-gradient,
       which renders via interpolated vertex colours and shows hard 8-bit alpha
       banding over light backgrounds). linear-gradient is computed per-pixel in
       our GL3 fragment shader, which also applies ~1 LSB TPDF dither to break the
       alpha-ramp banding as it fades to transparent. */
    decorator: linear-gradient( to right, #000000ff, #00000000 );
    padding: 8dp;
    font-family: Noto Sans;
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow-x: hidden;
    overflow-y: auto;
}
/* DECLARATIVE EASING CARRIER for the C++ animator (d1 fix). This `transition` is
   NOT animated by RmlUi: RmlUi only starts a CSS transition on a class/definition
   change, and `slide` is driven through the inline data-style-transform above,
   which RmlUi never animates. Instead the C++ SlideAnimator READS this transition
   (duration + tween) via UiSurface::transition_timing("panel", "transform") and
   drives slide_px_ itself, frame by frame — so editing the duration/tween here
   hot-reloads the on-seat feel with no recompile. The element id="panel" is what
   transition_timing looks the element up by. NOTE: RmlUi 6.2 has NO bare `linear`
   keyword — use a named tween; `cubic-in-out` is the authored ease here. */
#panel {
    transition: transform 0.36s cubic-in-out;
}
/* Hide both scrollbars (the rail scrolls, but no visible scrollbar). RmlUi
   instances scrollbarvertical/scrollbarhorizontal elements; width/height 0 hides
   them (verified pattern: vendored Samples effects_style.rcss / invader.rcss). */
div.panel scrollbarvertical {
    width: 0dp;
}
div.panel scrollbarhorizontal {
    height: 0dp;
}
/* The slot WRAPPER. margin:auto on this single flex item vertically centers the
   card stack when it fits, and collapses to 0 free-space (top stays reachable,
   no clipping) when the cards overflow — the correct flex-center+overflow
   pattern (justify-content:center would strand/clip the top on overflow).
   flex-shrink:0 so the stack keeps its natural height and the container scrolls. */
div.rail {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex-shrink: 0;
    margin: auto 0;
}
@keyframes slot-enter {
    from {
        opacity: 0;
        transform: translateX(-12dp) scale(0.72);
    }
    to {
        opacity: 1;
        transform: translateX(0px) scale(1.0);
    }
}
div.slot {
    display: block;
    position: relative;
    width: 224dp;
    height: 140dp;
    min-height: 140dp;
    margin-bottom: 8dp;
    background-color: #2e2e32ff;
    border-radius: 10dp;
    overflow: hidden;
    transform-origin: 0% 0%;
    animation: slot-enter 0.16s cubic-out 1 normal;
}
div.slot div.thumb {
    /* OVERSCAN the slot by 2dp on every side: RmlUi resolves the inset/percent
       box anchored top-left, leaving the thumb ~2px short on the RIGHT so the
       #2e2e32 slot placeholder peeked through there (diagnosed real-seat: the
       sliver sampled as the placeholder, not the thumb). A negative inset makes
       the thumb a few dp LARGER than the slot; the slot's rounded overflow:hidden
       clips the overscan to the rounded card, so every edge is fully covered with
       no placeholder peek and the corners stay rounded. cover/center keeps the
       slightly-larger box fully covered + centered. */
    display: block;
    position: absolute;
    left: -2dp;
    top: -2dp;
    right: -2dp;
    bottom: -2dp;
}
div.slot span.title {
    /* Title overlay INTENTIONALLY NOT RENDERED (user decision): the card is
       thumbnail-only for now. display:none keeps the {{ row.title }} binding +
       the bind_list_string("slots","title", …) getter LIVE and compiling so the
       overlay can be re-enabled later by restoring `display: block`. The scrim
       squared off the thumbnail's rounded bottom corners + protruded on the
       right; hiding it lets all four corners round cleanly. */
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 4dp 6dp;
    background-color: #00000099;
    color: #f2f2f2ff;
    font-size: 13dp;
    text-align: center;
}