stremiok 0.0.0-stage → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +112 -2
- package/config.xml +45 -0
- package/css/fonts/OFL-atkinsonhyperlegible.txt +92 -0
- package/css/fonts/OFL-cousine.txt +93 -0
- package/css/fonts/OFL-nunito.txt +93 -0
- package/css/fonts/OFL-roboto.txt +93 -0
- package/css/fonts/atkinson-latin-ext.woff2 +0 -0
- package/css/fonts/atkinson-latin.woff2 +0 -0
- package/css/fonts/cousine-cyrillic.woff2 +0 -0
- package/css/fonts/cousine-latin-ext.woff2 +0 -0
- package/css/fonts/cousine-latin.woff2 +0 -0
- package/css/fonts/nunito-cyrillic.woff2 +0 -0
- package/css/fonts/nunito-latin-ext.woff2 +0 -0
- package/css/fonts/nunito-latin.woff2 +0 -0
- package/css/fonts/roboto-cyrillic.woff2 +0 -0
- package/css/fonts/roboto-latin-ext.woff2 +0 -0
- package/css/fonts/roboto-latin.woff2 +0 -0
- package/css/style.css +507 -0
- package/icon.png +0 -0
- package/index.html +86 -0
- package/js/app.js +316 -0
- package/js/downloads.js +207 -0
- package/js/focus.js +228 -0
- package/js/hubpreview.js +71 -0
- package/js/iptv.js +484 -0
- package/js/keys.js +113 -0
- package/js/local.js +888 -0
- package/js/player-audio.js +281 -0
- package/js/player-controls.js +963 -0
- package/js/player-core.js +1157 -0
- package/js/player-lang.js +127 -0
- package/js/player-quality.js +319 -0
- package/js/player-store.js +267 -0
- package/js/player-subs.js +690 -0
- package/js/player.js +17 -0
- package/js/polyfills.js +47 -0
- package/js/qrcode.js +2297 -0
- package/js/stremio-account.js +76 -0
- package/js/stremio.js +1983 -0
- package/js/trakt.js +844 -0
- package/js/tvapps.js +180 -0
- package/js/util.js +1488 -0
- package/js/view-core.js +751 -0
- package/js/view-detail.js +2312 -0
- package/js/view-discover.js +574 -0
- package/js/view-home.js +1436 -0
- package/js/view-search.js +342 -0
- package/js/view-settings.js +2021 -0
- package/js/views.js +19 -0
- package/js/youtube.js +359 -0
- package/js/ytplay.js +177 -0
- package/package.json +53 -4
- package/service/cacert.pem +2950 -0
- package/service/index.js +2167 -0
- package/service/preview.js +44 -0
package/css/style.css
ADDED
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
/* StremioK for Tizen 3.0 — conservative CSS (no CSS grid gap edge cases, flexbox is fine on Chromium 47) */
|
|
2
|
+
/* Sentinel: app.js checks this element's width to confirm the stylesheet applied. */
|
|
3
|
+
#css-sentinel { width: 11px; }
|
|
4
|
+
|
|
5
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
6
|
+
|
|
7
|
+
html, body {
|
|
8
|
+
width: 1920px;
|
|
9
|
+
height: 1080px;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
background: #0e1117;
|
|
12
|
+
color: #e6e9ef;
|
|
13
|
+
font-family: Arial, "Tizen Sans", sans-serif;
|
|
14
|
+
-webkit-user-select: none;
|
|
15
|
+
user-select: none;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* --- Video planes --- */
|
|
19
|
+
#av-player, #html5-player {
|
|
20
|
+
position: absolute;
|
|
21
|
+
top: 0; left: 0;
|
|
22
|
+
width: 1920px; height: 1080px;
|
|
23
|
+
background: #000;
|
|
24
|
+
display: none;
|
|
25
|
+
z-index: 1;
|
|
26
|
+
}
|
|
27
|
+
#av-player.active, #html5-player.active { display: block; }
|
|
28
|
+
|
|
29
|
+
#app { position: absolute; top: 0; left: 0; width: 1920px; height: 1080px; z-index: 10; }
|
|
30
|
+
.screen { position: absolute; top: 0; left: 0; width: 1920px; height: 1080px; }
|
|
31
|
+
.hidden { display: none !important; }
|
|
32
|
+
|
|
33
|
+
/* --- Header --- */
|
|
34
|
+
.header { height: 96px; padding: 30px 60px 0 60px; display: flex; align-items: center; }
|
|
35
|
+
.brand { font-size: 40px; font-weight: bold; color: #818cf8; letter-spacing: 1px; }
|
|
36
|
+
.brand .dot { color: #e6e9ef; }
|
|
37
|
+
/* private viewing on: StremioK as an outline (the fill hidden; the outline takes each letter's
|
|
38
|
+
own color, so it follows the accent color and a light background) */
|
|
39
|
+
.brand.private, .brand.private .dot { -webkit-text-fill-color: transparent; -webkit-text-stroke-width: 1.5px; }
|
|
40
|
+
.header .spacer { flex: 1; }
|
|
41
|
+
.header-title { font-size: 36px; font-weight: bold; }
|
|
42
|
+
/* Search and Settings: pills like the tabs (the top menu fits every tab, Local included, at 1920 px) */
|
|
43
|
+
.header .hchip { display: inline-flex; align-items: center; font-size: 22px; padding: 8px 13px; margin-right: 6px; border-radius: 28px; background: #1a1f2b; color: #aeb6c4; border: 4px solid transparent; white-space: nowrap; }
|
|
44
|
+
.header .hchip.focusable.focused { background: #818cf8; color: #0e1117; border-color: #fff; opacity: 1; }
|
|
45
|
+
|
|
46
|
+
/* --- Rows --- */
|
|
47
|
+
.rows { position: absolute; top: 110px; left: 0; right: 0; bottom: 0; overflow: hidden; }
|
|
48
|
+
.row { margin: 0 0 16px 0; }
|
|
49
|
+
.row-title { font-size: 26px; font-weight: bold; margin: 0 0 8px 60px; color: #c7cbd4; }
|
|
50
|
+
/* vertical padding leaves room for the scaled focus ring (overflow clips the rest) */
|
|
51
|
+
.row-scroller { white-space: nowrap; padding: 26px 60px; overflow: hidden; }
|
|
52
|
+
|
|
53
|
+
/* --- Cards --- */
|
|
54
|
+
.card {
|
|
55
|
+
display: inline-block;
|
|
56
|
+
width: 200px;
|
|
57
|
+
height: 300px;
|
|
58
|
+
margin-right: 22px;
|
|
59
|
+
border-radius: 10px;
|
|
60
|
+
background: #1a1f2b;
|
|
61
|
+
vertical-align: top;
|
|
62
|
+
position: relative;
|
|
63
|
+
overflow: hidden;
|
|
64
|
+
border: 4px solid transparent;
|
|
65
|
+
}
|
|
66
|
+
.card .poster { width: 100%; height: 100%; display: block; background-size: cover; background-position: center; }
|
|
67
|
+
.card .fallback { display: flex; align-items: center; justify-content: center; height: 100%; padding: 10px; font-size: 20px; color: #8b93a5; text-align: center; white-space: normal; }
|
|
68
|
+
.card .cap { position: absolute; bottom: 0; left: 0; right: 0; padding: 26px 10px 8px 10px; font-size: 18px; background: linear-gradient(transparent, rgba(0,0,0,0.85)); white-space: normal; line-height: 1.2; max-height: 70px; overflow: hidden; }
|
|
69
|
+
.card .prog { position: absolute; bottom: 0; left: 0; height: 6px; background: #818cf8; }
|
|
70
|
+
|
|
71
|
+
/* --- Focus state (TV) --- */
|
|
72
|
+
.focusable.focused { border-color: #a5b4fc; box-shadow: 0 0 0 3px rgba(129,140,248,0.85); }
|
|
73
|
+
|
|
74
|
+
/* Carousel cards: bold, obvious focus — white inner border + indigo ring + lift.
|
|
75
|
+
No blurred drop shadow: a large blur is repainted on every D-pad move and is
|
|
76
|
+
expensive on older TV GPUs; the ring + scale carry the focus on their own. */
|
|
77
|
+
.card.focusable.focused {
|
|
78
|
+
border-color: #ffffff;
|
|
79
|
+
box-shadow: 0 0 0 5px #6366f1;
|
|
80
|
+
transform: scale(1.09);
|
|
81
|
+
z-index: 5;
|
|
82
|
+
}
|
|
83
|
+
.card.focusable.moving { border-color: #ffffff; box-shadow: 0 0 0 5px #f59e0b; transform: scale(1.09); z-index: 6; }
|
|
84
|
+
|
|
85
|
+
/* Filled selection for list rows / buttons */
|
|
86
|
+
.pill.focusable.focused, .stream.focusable.focused, .ep.focusable.focused { background: #818cf8; color: #0e1117; }
|
|
87
|
+
/* Keep secondary lines readable on the bright selected background */
|
|
88
|
+
.stream.focusable.focused .s-sub, .ep.focusable.focused .ep-sub,
|
|
89
|
+
.ep.focusable.focused .ep-ov, .ep.focusable.focused .ep-rating { color: #17203a; }
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
/* --- Detail screen --- */
|
|
93
|
+
.detail-hero { position: absolute; top: 0; left: 0; right: 0; height: 620px; background-size: cover; background-position: center top; }
|
|
94
|
+
.detail-hero .shade { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(90deg, rgba(14,17,23,0.96) 30%, rgba(14,17,23,0.35) 100%), linear-gradient(0deg, #0e1117 4%, transparent 40%); }
|
|
95
|
+
/* The source and episode lists: the backdrop over the whole screen, shaded lighter, the rows
|
|
96
|
+
see-through (a focused one stays solid) */
|
|
97
|
+
.detail-hero.hero-full { height: 1080px; }
|
|
98
|
+
.detail-hero.hero-full .shade { background: linear-gradient(90deg, rgba(14,17,23,0.9) 22%, rgba(14,17,23,0.4) 100%), linear-gradient(0deg, rgba(14,17,23,0.5) 0%, transparent 45%); }
|
|
99
|
+
.streams-panel .stream, .list-panel .ep { background: rgba(22,27,38,0.7); }
|
|
100
|
+
.streams-panel .stream-group, .streams-panel .stream-for, .streams-panel .streams-hidden { text-shadow: 0 1px 3px #000, 0 0 8px rgba(0,0,0,0.6); }
|
|
101
|
+
#screen-detail .header { position: relative; z-index: 3; } /* the main menu, over the backdrop */
|
|
102
|
+
/* the block spans the screen so a row of buttons never wraps (the TV's font is wider than
|
|
103
|
+
desktop Arial); the text inside keeps a readable measure */
|
|
104
|
+
.detail-body { position: absolute; top: 150px; left: 60px; right: 60px; } /* below the top menu */
|
|
105
|
+
.detail-title { font-size: 54px; font-weight: bold; margin-bottom: 14px; }
|
|
106
|
+
.detail-meta { font-size: 22px; color: #a7adba; margin-bottom: 18px; max-width: 1200px; }
|
|
107
|
+
.detail-desc { font-size: 22px; line-height: 1.45; color: #cfd3dc; max-height: 200px; overflow: hidden; margin-bottom: 26px; max-width: 1000px; }
|
|
108
|
+
.btn-row { margin-top: 10px; white-space: nowrap; }
|
|
109
|
+
.pill { display: inline-block; padding: 14px 30px; margin-right: 16px; border-radius: 30px; background: #1a1f2b; font-size: 22px; border: 4px solid transparent; }
|
|
110
|
+
/* selected season: gray with light text; focus must still win (higher specificity below) */
|
|
111
|
+
.season-bar .pill.season-sel { background: #2a3346; color: #c7cbd4; }
|
|
112
|
+
.season-bar .pill.focusable.focused { background: #818cf8; color: #0e1117; }
|
|
113
|
+
|
|
114
|
+
/* Episode + stream lists */
|
|
115
|
+
.list-panel { position: absolute; top: 640px; left: 60px; right: 60px; bottom: 40px; overflow: hidden; }
|
|
116
|
+
.season-bar { margin-bottom: 14px; white-space: nowrap; }
|
|
117
|
+
.ep, .stream { display: block; padding: 16px 22px; margin-bottom: 10px; background: #161b26; border-radius: 8px; font-size: 22px; border: 4px solid transparent; white-space: normal; }
|
|
118
|
+
.ep .ep-sub, .stream .s-sub { display: block; font-size: 17px; color: #9aa2b1; margin-top: 4px; }
|
|
119
|
+
|
|
120
|
+
/* episode rows with thumbnail + rating */
|
|
121
|
+
.ep-row { display: flex; align-items: flex-start; padding: 12px 16px; height: 108px; overflow: hidden; }
|
|
122
|
+
.ep-thumb { width: 120px; height: 68px; flex: 0 0 120px; margin-right: 18px; border-radius: 6px; background-color: #0e1117; background-size: cover; background-position: center; position: relative; overflow: hidden; }
|
|
123
|
+
/* partly watched episode: progress along the bottom of its thumbnail */
|
|
124
|
+
.ep-prog { position: absolute; left: 0; bottom: 0; height: 5px; background: #818cf8; }
|
|
125
|
+
.ep-body { flex: 1; min-width: 0; }
|
|
126
|
+
.ep-line { display: flex; align-items: flex-start; font-size: 22px; }
|
|
127
|
+
.ep-title { flex: 1 1 auto; min-width: 0; }
|
|
128
|
+
.ep-rating { flex: 0 0 auto; margin-left: 14px; color: #ffd257; font-size: 19px; white-space: nowrap; }
|
|
129
|
+
.ep-rating:empty { margin-left: 0; }
|
|
130
|
+
.airs-pill { background: transparent; border-color: #818cf8; color: #818cf8; } /* a series' next episode isn't out yet (not a button) */
|
|
131
|
+
.ep-airs { flex: 0 0 auto; margin-left: 14px; padding: 1px 10px; border-radius: 6px; border: 2px solid #818cf8; color: #818cf8; font-size: 17px; white-space: nowrap; }
|
|
132
|
+
.ep.unaired { opacity: 0.7; }
|
|
133
|
+
.ep.unaired.focused { opacity: 1; }
|
|
134
|
+
.ep.focusable.focused .ep-airs { border-color: #17203a; color: #17203a; }
|
|
135
|
+
.ep-ov { display: block; font-size: 17px; color: #9aa2b1; margin-top: 6px; max-height: 44px; overflow: hidden; }
|
|
136
|
+
.list-scroll { position: absolute; top: 0; left: 0; right: 0; bottom: 0; overflow: hidden; }
|
|
137
|
+
|
|
138
|
+
/* Series info page. The text block (just below the top menu) is capped; the panel under it
|
|
139
|
+
starts where the block ends (view-detail.js fitPanel; 456px until measured). The panel is
|
|
140
|
+
a fixed 84px season strip + the episode list (118px rows: 108 + 10 gap), with the 70px
|
|
141
|
+
margin Focus keeps below the focused row. Nothing in .series-panel overflows it, so Focus
|
|
142
|
+
scrolls only the episode list and the season strip always stays in view (it scrolls
|
|
143
|
+
sideways on its own when there are many). */
|
|
144
|
+
.series-body { top: 110px; max-height: 388px; overflow: hidden; }
|
|
145
|
+
.series-body .detail-desc { max-height: 128px; margin-bottom: 0; } /* 4 lines */
|
|
146
|
+
/* Resume / Play (padding keeps the focus ring inside the clipped text block) */
|
|
147
|
+
.series-body .series-actions, .series-body .streams-actions { margin-top: 12px; padding: 4px; }
|
|
148
|
+
.series-panel { top: 456px; bottom: 30px; }
|
|
149
|
+
/* A source list (a movie, an episode, a channel): no season row, so the list starts
|
|
150
|
+
where a series has its seasons, under the same compact text block. */
|
|
151
|
+
.streams-panel { top: 456px; bottom: 30px; }
|
|
152
|
+
.streams-panel .list-scroll { padding: 4px 6px; }
|
|
153
|
+
.series-panel .season-bar { height: 84px; margin: 0; padding: 6px; overflow: hidden; }
|
|
154
|
+
.series-panel .list-scroll { top: 84px; padding: 4px 6px; }
|
|
155
|
+
/* Files of a download (e.g. a RealDebrid season pack): same area, no season strip. */
|
|
156
|
+
.files-panel { top: 456px; bottom: 30px; }
|
|
157
|
+
.files-panel .list-scroll { padding: 4px 6px; }
|
|
158
|
+
|
|
159
|
+
/* Settings */
|
|
160
|
+
.settings-wrap { position: absolute; top: 120px; left: 60px; right: 60px; bottom: 40px; overflow: hidden; }
|
|
161
|
+
.back-row { color: #c7cbd4; }
|
|
162
|
+
/* Home Feeds ordering */
|
|
163
|
+
.feed-row { display: flex; align-items: center; margin-bottom: 8px; }
|
|
164
|
+
.feed-btn { width: 60px; text-align: center; padding: 14px 0; margin-right: 8px; background: #161b26; border-radius: 8px; font-size: 22px; border: 4px solid transparent; }
|
|
165
|
+
.feed-name { flex: 1; padding: 14px 18px; background: #161b26; border-radius: 8px; font-size: 22px; border: 4px solid transparent; white-space: normal; }
|
|
166
|
+
.feed-off .feed-name { opacity: 0.5; }
|
|
167
|
+
.feed-btn.focusable.focused, .feed-name.focusable.focused { background: #818cf8; color: #0e1117; border-color: #fff; }
|
|
168
|
+
.settings-wrap h2 { font-size: 30px; margin-bottom: 20px; }
|
|
169
|
+
.addon-item { padding: 16px 20px; margin-bottom: 10px; background: #161b26; border-radius: 8px; font-size: 20px; border: 4px solid transparent; word-break: break-all; white-space: normal; }
|
|
170
|
+
.addon-item .a-name { font-weight: bold; }
|
|
171
|
+
.addon-item .a-url { font-size: 15px; color: #8b93a5; }
|
|
172
|
+
.addon-item .addon-said { color: #f0a5a5; margin-top: 4px; white-space: normal; } /* a failed addon's own error message */
|
|
173
|
+
.hint { color: #8b93a5; font-size: 18px; margin-top: 20px; line-height: 1.5; }
|
|
174
|
+
.feeds-hint { margin: 10px 0 14px; }
|
|
175
|
+
.settings-version { position: absolute; right: 60px; bottom: 10px; font-size: 18px; color: #6f7788; }
|
|
176
|
+
|
|
177
|
+
/* --- Add-addon page (field kept high, above the on-screen keyboard) --- */
|
|
178
|
+
.add-wrap { position: absolute; top: 120px; left: 60px; right: 60px; }
|
|
179
|
+
.add-hint { font-size: 22px; color: #8b93a5; margin-bottom: 28px; line-height: 1.4; max-width: 1200px; }
|
|
180
|
+
.add-input { width: 100%; padding: 20px 24px; font-size: 32px; background: #0e1117; color: #fff; border: 4px solid #2a3346; border-radius: 12px; }
|
|
181
|
+
.add-input.focused { border-color: #818cf8; box-shadow: 0 0 0 2px rgba(129,140,248,0.5); }
|
|
182
|
+
.add-btn-row { margin-top: 34px; }
|
|
183
|
+
.add-btn-row .pill { min-width: 220px; text-align: center; }
|
|
184
|
+
.cfg-row .a-url { color: #6f7788; }
|
|
185
|
+
|
|
186
|
+
/* --- Player OSD --- */
|
|
187
|
+
#player-osd { position: absolute; left: 0; right: 0; bottom: 0; height: 220px; z-index: 20; padding: 40px 60px; background: linear-gradient(transparent, rgba(0,0,0,0.9)); }
|
|
188
|
+
#osd-title { font-size: 30px; font-weight: bold; margin-bottom: 20px; }
|
|
189
|
+
#osd-bar { position: relative; height: 8px; background: rgba(255,255,255,0.2); border-radius: 4px; }
|
|
190
|
+
#osd-buffer { position: absolute; top: 0; left: 0; height: 8px; background: rgba(255,255,255,0.35); border-radius: 4px; width: 0; }
|
|
191
|
+
#osd-progress { position: absolute; top: 0; left: 0; height: 8px; background: #818cf8; border-radius: 4px; width: 0; z-index: 2; }
|
|
192
|
+
/* Scrub preview (LEFT/RIGHT, FF/REW): the stretch being jumped over, a marker at the
|
|
193
|
+
landing point and a time bubble above it. The seek happens once the presses stop. */
|
|
194
|
+
#osd-chapter { margin: -14px 0 10px; font-size: 22px; color: #c7d2fe; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
195
|
+
#osd-sponsor { position: absolute; top: 0; left: 0; right: 0; height: 8px; z-index: 3; }
|
|
196
|
+
.osd-sb { position: absolute; top: 0; height: 8px; opacity: 0.85; }
|
|
197
|
+
.osd-sb-poi { position: absolute; top: -4px; width: 8px; height: 16px; margin-left: -4px; background: #fff; border: 2px solid #000; }
|
|
198
|
+
#osd-chapters { position: absolute; top: 0; left: 0; right: 0; height: 8px; z-index: 3; }
|
|
199
|
+
.osd-chapter-mark { position: absolute; top: -1px; width: 4px; height: 10px; margin-left: -2px; background: #000; }
|
|
200
|
+
#osd-scrub-range { position: absolute; top: 0; height: 8px; background: rgba(165,180,252,0.5); border-radius: 4px; z-index: 3; }
|
|
201
|
+
#osd-scrub { position: absolute; top: -9px; width: 6px; height: 26px; margin-left: -3px; background: #fff; border-radius: 3px; box-shadow: 0 0 0 2px #6366f1; z-index: 4; }
|
|
202
|
+
#osd-scrub-time { position: absolute; bottom: 34px; left: 50%; -webkit-transform: translateX(-50%); transform: translateX(-50%); white-space: nowrap; font-size: 26px; font-weight: bold; color: #fff; background: rgba(20,25,36,0.96); border: 2px solid #6366f1; padding: 6px 14px; border-radius: 8px; }
|
|
203
|
+
#osd-scrub.edge-l #osd-scrub-time { left: 0; -webkit-transform: none; transform: none; }
|
|
204
|
+
#osd-scrub.edge-r #osd-scrub-time { left: auto; right: 0; -webkit-transform: none; transform: none; }
|
|
205
|
+
#osd-times { display: flex; justify-content: space-between; margin-top: 10px; font-size: 20px; color: #cfd3dc; }
|
|
206
|
+
#osd-times .osd-right { display: flex; align-items: center; }
|
|
207
|
+
#osd-tags { font-size: 17px; color: #9aa2b1; margin-right: 18px; letter-spacing: 0.3px; } /* (what's playing, in short) */
|
|
208
|
+
#osd-tags:empty { display: none; }
|
|
209
|
+
#osd-cur.live { color: #ff4d4d; font-weight: bold; letter-spacing: 1px; }
|
|
210
|
+
#osd-hint { margin-top: 14px; font-size: 18px; color: #8b93a5; }
|
|
211
|
+
|
|
212
|
+
/* --- Subtitles --- */
|
|
213
|
+
#subs { position: absolute; left: 0; right: 0; bottom: 130px; z-index: 18; text-align: center; padding: 0 140px; }
|
|
214
|
+
#subs2 { position: absolute; left: 0; right: 0; top: 60px; z-index: 18; text-align: center; padding: 0 140px; } /* (the second subtitle, at the top) */
|
|
215
|
+
#subs2 span { display: inline-block; background: rgba(0,0,0,0.6); color: #fff; font-size: 36px; line-height: 1.4; padding: 4px 16px; border-radius: 6px; white-space: pre-wrap; text-shadow: 0 2px 3px #000; }
|
|
216
|
+
#subs span { display: inline-block; background: rgba(0,0,0,0.6); color: #fff; font-size: 36px; line-height: 1.4; padding: 4px 16px; border-radius: 6px; white-space: pre-wrap; text-shadow: 0 2px 3px #000; }
|
|
217
|
+
|
|
218
|
+
#sub-menu { position: absolute; right: 60px; bottom: 250px; width: 560px; max-height: 620px; overflow: hidden; z-index: 30; background: rgba(20,25,36,0.98); border-radius: 12px; padding: 18px; }
|
|
219
|
+
#sub-menu .sm-title { font-size: 24px; font-weight: bold; margin-bottom: 12px; color: #c7cbd4; }
|
|
220
|
+
#sub-menu .sm-list { max-height: 520px; overflow: hidden; }
|
|
221
|
+
#sub-menu .sm-item { padding: 12px 16px; border-radius: 8px; border: 3px solid transparent; }
|
|
222
|
+
#sub-menu .sm-item .sm-main { font-size: 22px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
223
|
+
#sub-menu .sm-item .sm-detail { font-size: 16px; color: #9aa2b1; margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
224
|
+
#sub-menu .sm-item.sm-tall .sm-detail { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; max-height: 42px; line-height: 21px; }
|
|
225
|
+
#sub-menu .sm-item.sel { background: #818cf8; color: #0e1117; }
|
|
226
|
+
#sub-menu .sm-item.sel .sm-detail { color: #26304a; }
|
|
227
|
+
|
|
228
|
+
/* --- Search --- */
|
|
229
|
+
.search-wrap { position: absolute; top: 120px; left: 60px; right: 60px; bottom: 40px; }
|
|
230
|
+
.search-bar { display: flex; margin-bottom: 26px; }
|
|
231
|
+
#search-input { flex: 1; padding: 16px 20px; font-size: 26px; background: #0e1117; color: #fff; border: 4px solid #2a3346; border-radius: 8px; }
|
|
232
|
+
#search-input.focused { border-color: #818cf8; }
|
|
233
|
+
.search-go { margin-left: 16px; }
|
|
234
|
+
/* Results keep exactly 7 portrait columns (7 x 222px - 22 = 1532px + padding, with room
|
|
235
|
+
on the right for the focused card's scale + ring); the ~220px that used to sit empty
|
|
236
|
+
to their right holds the recent-searches column. */
|
|
237
|
+
.search-results { position: absolute; top: 96px; left: 0; right: 228px; bottom: 0; overflow: hidden; white-space: normal; padding: 22px 16px 22px 0; }
|
|
238
|
+
.search-results .card { margin: 0 22px 24px 0; }
|
|
239
|
+
/* results: one row per catalog (the rows scroll sideways, the list up and down). The
|
|
240
|
+
row's padding leaves room for the focused card's zoom and ring (about 14px each side),
|
|
241
|
+
which the row would otherwise clip on the first card's left edge. */
|
|
242
|
+
.search-results .row-title { margin-left: 24px; font-size: 24px; }
|
|
243
|
+
.search-results .row-scroller { padding: 26px 24px; }
|
|
244
|
+
.search-results .row .card { margin: 0 22px 0 0; }
|
|
245
|
+
.search-empty { font-size: 24px; color: #8b93a5; margin-top: 30px; }
|
|
246
|
+
/* while a search's sources answer (and, after, the ones that didn't) */
|
|
247
|
+
.search-status { display: flex; align-items: center; margin: 0 0 10px 24px; font-size: 22px; color: #8b93a5; min-height: 34px; }
|
|
248
|
+
.search-status .spin-small { width: 22px; height: 22px; border-width: 4px; margin-right: 14px; flex: 0 0 auto; }
|
|
249
|
+
.search-status-warn { color: #f0a5a5; }
|
|
250
|
+
.search-recent { position: absolute; top: 96px; right: 0; width: 216px; bottom: 0; overflow: hidden; padding: 22px 4px 0 4px; }
|
|
251
|
+
.recent-title { font-size: 18px; color: #8b93a5; margin-bottom: 12px; }
|
|
252
|
+
.recent-item { padding: 12px 14px; margin-bottom: 10px; background: #161b26; border-radius: 8px; font-size: 20px; border: 4px solid transparent; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
253
|
+
.recent-item.focusable.focused { background: #818cf8; color: #0e1117; border-color: #fff; }
|
|
254
|
+
|
|
255
|
+
/* --- Stream info overlay (player menu) --- */
|
|
256
|
+
#stream-info { position: absolute; top: 50px; right: 60px; z-index: 26; min-width: 460px; max-width: 760px; background: rgba(14,17,23,0.9); border: 2px solid #2a3346; border-radius: 12px; padding: 16px 22px; font-size: 20px; }
|
|
257
|
+
#stream-info .si-row { display: flex; padding: 3px 0; }
|
|
258
|
+
#stream-info .si-k { flex: 0 0 130px; color: #8b93a5; }
|
|
259
|
+
#stream-info .si-v { flex: 1; color: #e6e9ef; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
260
|
+
|
|
261
|
+
/* --- Home: focused title's details between the top menu and the rows --- */
|
|
262
|
+
.home-info + .rows { top: 274px; } /* rows start just below the details strip, so it reads as theirs */
|
|
263
|
+
/* Details strip: a clear gap under the top menu, sitting right on top of the rows.
|
|
264
|
+
Inset so its text lines up with the row titles (36 + 5 + 19 = 60px); shaded only while it
|
|
265
|
+
describes a title (.on). */
|
|
266
|
+
.home-info { position: absolute; top: 117px; left: 36px; right: 36px; height: 142px; box-sizing: border-box;
|
|
267
|
+
padding: 10px 24px 10px 19px; overflow: hidden; border-radius: 12px; border-left: 5px solid transparent; }
|
|
268
|
+
.home-info.on { background: linear-gradient(90deg, rgba(129,140,248,0.20) 0%, rgba(129,140,248,0.07) 55%, rgba(129,140,248,0.02) 100%);
|
|
269
|
+
border-left-color: #818cf8; }
|
|
270
|
+
.home-info-title { font-size: 30px; line-height: 36px; font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
271
|
+
.home-info-meta { font-size: 20px; line-height: 24px; color: #a7adba; margin: 4px 0 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
272
|
+
.home-info-desc { font-size: 19px; line-height: 26px; color: #cfd3dc; max-height: 52px; overflow: hidden; max-width: 1400px; }
|
|
273
|
+
|
|
274
|
+
/* --- Watched mark on posters --- */
|
|
275
|
+
.card .card-rating { position: absolute; top: 8px; left: 8px; z-index: 2; padding: 3px 9px; border-radius: 12px; background: rgba(0,0,0,0.72); color: #ffd257; font-size: 17px; font-weight: bold; }
|
|
276
|
+
.card .card-watched { position: absolute; top: 8px; right: 8px; z-index: 2; width: 34px; height: 34px; line-height: 34px; text-align: center; border-radius: 17px; background: rgba(99,102,241,0.95); color: #fff; font-size: 20px; font-weight: bold; }
|
|
277
|
+
|
|
278
|
+
/* --- Contextual quick-action bar (UP) --- */
|
|
279
|
+
#player-bar { position: absolute; left: 0; right: 0; bottom: 250px; z-index: 22; text-align: center; white-space: nowrap; } /* (up to ten buttons: one line, compact) */
|
|
280
|
+
#player-bar .pb-btn { display: inline-block; margin: 0 6px; padding: 14px 22px; font-size: 24px; border-radius: 40px; background: rgba(22,27,38,0.95); border: 4px solid transparent; color: #e6e9ef; }
|
|
281
|
+
#player-bar .pb-btn.sel { background: #818cf8; color: #0e1117; border-color: #fff; }
|
|
282
|
+
/* Cast & crew over the video (quick bar): a strip of photos, moved to keep the selected one in view */
|
|
283
|
+
#cast-strip { position: absolute; left: 0; right: 0; bottom: 230px; z-index: 23; padding: 18px 60px 22px 60px; background: rgba(0,0,0,0.55); overflow: hidden; } /* see-through, like the subtitles' default box; dark whatever the Appearance background */
|
|
284
|
+
#cast-strip .cs-head { display: flex; align-items: baseline; margin-bottom: 14px; }
|
|
285
|
+
#cast-strip .cs-title { flex: 1; font-size: 24px; font-weight: bold; color: #e6e9ef; text-shadow: 0 1px 3px rgba(0,0,0,0.9); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
286
|
+
#cast-strip .cs-hint { flex: 0 0 auto; margin-left: 24px; font-size: 18px; color: #b4bac6; text-shadow: 0 1px 3px rgba(0,0,0,0.9); white-space: pre; }
|
|
287
|
+
#cast-strip .cs-strip { white-space: nowrap; height: 330px; }
|
|
288
|
+
#cast-strip .cs-card { display: inline-block; vertical-align: top; width: 172px; margin-right: 24px; white-space: normal; }
|
|
289
|
+
#cast-strip .cs-photo { display: block; box-sizing: border-box; width: 172px; height: 240px; object-fit: cover; border-radius: 10px; background: #1a1f2b; border: 4px solid transparent; }
|
|
290
|
+
#cast-strip .cs-none { line-height: 240px; text-align: center; font-size: 72px; color: #4b5366; }
|
|
291
|
+
#cast-strip .cs-card.sel .cs-photo { border-color: #818cf8; }
|
|
292
|
+
#cast-strip .cs-name { font-size: 20px; color: #e6e9ef; text-shadow: 0 1px 3px rgba(0,0,0,0.9); margin-top: 8px; max-height: 50px; overflow: hidden; }
|
|
293
|
+
#cast-strip .cs-role { font-size: 16px; color: #b4bac6; text-shadow: 0 1px 3px rgba(0,0,0,0.9); max-height: 40px; overflow: hidden; }
|
|
294
|
+
#cast-strip .cs-card.sel .cs-name { color: #818cf8; }
|
|
295
|
+
#cast-strip .cs-note { font-size: 20px; color: #8b93a5; }
|
|
296
|
+
/* A YouTube video's end screen (its linked videos) and cards, over the video */
|
|
297
|
+
#yt-links { position: absolute; left: 0; right: 0; bottom: 230px; z-index: 23; padding: 18px 60px 22px 60px; background: rgba(0,0,0,0.55); }
|
|
298
|
+
#yt-links .yl-head { display: flex; align-items: baseline; margin-bottom: 14px; }
|
|
299
|
+
#yt-links .yl-heading { flex: 1; font-size: 24px; font-weight: bold; color: #e6e9ef; text-shadow: 0 1px 3px rgba(0,0,0,0.9); }
|
|
300
|
+
#yt-links .yl-hint { font-size: 18px; color: #b4bac6; white-space: pre; text-shadow: 0 1px 3px rgba(0,0,0,0.9); }
|
|
301
|
+
#yt-links .yl-row { white-space: nowrap; overflow: hidden; }
|
|
302
|
+
#yt-links .yl-card { display: inline-block; vertical-align: top; width: 320px; margin-right: 24px; white-space: normal; }
|
|
303
|
+
#yt-links .yl-thumb { display: block; box-sizing: border-box; width: 320px; height: 180px; border-radius: 10px; background: #1a1f2b; border: 4px solid transparent; object-fit: cover; }
|
|
304
|
+
#yt-links .yl-card.sel .yl-thumb { border-color: #818cf8; }
|
|
305
|
+
#yt-links .yl-title { font-size: 20px; color: #e6e9ef; margin-top: 8px; max-height: 52px; overflow: hidden; text-shadow: 0 1px 3px rgba(0,0,0,0.9); }
|
|
306
|
+
#yt-links .yl-card.sel .yl-title { color: #818cf8; }
|
|
307
|
+
#yt-card { position: absolute; right: 60px; top: 60px; z-index: 24; max-width: 520px; padding: 14px 20px; border-radius: 12px; background: rgba(0,0,0,0.7); border-left: 4px solid #818cf8; }
|
|
308
|
+
#yt-card .yc-teaser { font-size: 20px; color: #e6e9ef; }
|
|
309
|
+
#yt-card .yc-title { font-size: 18px; color: #b4bac6; margin-top: 4px; max-height: 48px; overflow: hidden; }
|
|
310
|
+
#yt-card .yc-hint { font-size: 16px; color: #818cf8; margin-top: 6px; }
|
|
311
|
+
|
|
312
|
+
/* --- Skip intro/recap/credits prompt --- */
|
|
313
|
+
#skip-prompt { position: absolute; right: 60px; bottom: 250px; z-index: 24; text-align: right; }
|
|
314
|
+
#skip-prompt .skip-btn { display: inline-block; margin-left: 12px; padding: 16px 30px; font-size: 26px; font-weight: bold; border-radius: 10px; background: rgba(22,27,38,0.96); border: 4px solid #818cf8; color: #e6e9ef; }
|
|
315
|
+
#skip-prompt .skip-btn.sel { background: #818cf8; color: #0e1117; border-color: #fff; }
|
|
316
|
+
|
|
317
|
+
/* --- Landscape poster mode --- */
|
|
318
|
+
.card .poster { object-fit: cover; }
|
|
319
|
+
.card.landscape { width: 340px; height: 200px; }
|
|
320
|
+
|
|
321
|
+
/* --- Confirm modal --- */
|
|
322
|
+
.modal-overlay { position: absolute; top: 0; left: 0; width: 1920px; height: 1080px; z-index: 45; background: rgba(0,0,0,0.72); display: flex; align-items: center; justify-content: center; }
|
|
323
|
+
.modal-box { width: 820px; background: #161b26; border: 2px solid #2a3346; border-radius: 16px; padding: 44px 48px; text-align: center; }
|
|
324
|
+
.modal-msg { font-size: 30px; line-height: 1.4; color: #e6e9ef; margin-bottom: 36px; }
|
|
325
|
+
.modal-row { display: flex; justify-content: center; }
|
|
326
|
+
.modal-btn { min-width: 200px; text-align: center; }
|
|
327
|
+
/* Watching's, an addon's and a playlist's menus: as wide as their buttons (each sized to its words, on one
|
|
328
|
+
line), within the screen; the name above wraps rather than widening it */
|
|
329
|
+
.actions-box { width: auto; min-width: 560px; max-width: 1760px; }
|
|
330
|
+
.actions-box .modal-btn { min-width: 0; white-space: nowrap; padding: 14px 24px; margin-right: 12px; }
|
|
331
|
+
.actions-box .modal-btn:last-child { margin-right: 0; }
|
|
332
|
+
/* Settings › IPTV: ▲ ▼ and the playlist (name, link, channels / downloaded, problem) */
|
|
333
|
+
.playlist-row { align-items: stretch; margin-bottom: 10px; }
|
|
334
|
+
.playlist-row .feed-btn { display: flex; align-items: center; justify-content: center; }
|
|
335
|
+
.playlist-row .playlist-item { flex: 1; margin-bottom: 0; }
|
|
336
|
+
.feed-off .playlist-item { opacity: 0.5; }
|
|
337
|
+
.playlist-item .addon-said:empty { display: none; }
|
|
338
|
+
/* list picker (single choice) */
|
|
339
|
+
.pick-box { width: 720px; text-align: left; }
|
|
340
|
+
.pick-box .modal-msg { text-align: left; margin-bottom: 20px; }
|
|
341
|
+
.pick-list { max-height: 620px; overflow: hidden; }
|
|
342
|
+
.pick-item { padding: 14px 20px; margin-bottom: 8px; border-radius: 8px; background: #0e1117; border: 4px solid transparent; font-size: 24px; }
|
|
343
|
+
.pick-item.sel { background: #2a3346; }
|
|
344
|
+
.pick-item.focusable.focused { background: #818cf8; color: #0e1117; border-color: #fff; }
|
|
345
|
+
|
|
346
|
+
/* Trakt connect overlay */
|
|
347
|
+
.trakt-connect { margin: 8px 0 28px; }
|
|
348
|
+
.trakt-connect .tc-line { font-size: 24px; color: #cfd3dc; margin: 10px 0; }
|
|
349
|
+
.trakt-connect .tc-line.small { font-size: 20px; color: #8b93a5; }
|
|
350
|
+
.trakt-connect .tc-url { font-size: 30px; font-weight: bold; color: #818cf8; margin: 6px 0; }
|
|
351
|
+
.trakt-connect .tc-qr { display: block; margin: 8px auto 4px; border-radius: 6px; } /* (white, with its quiet margin: drawn so) */
|
|
352
|
+
.trakt-connect .tc-code { font-size: 56px; font-weight: bold; letter-spacing: 6px; color: #fff; margin: 14px 0; }
|
|
353
|
+
|
|
354
|
+
.pill.danger { background: #3a2130; }
|
|
355
|
+
.pill.danger.focusable.focused { background: #ef4444; color: #fff; }
|
|
356
|
+
.reset-item .a-name { color: #f0a5a5; }
|
|
357
|
+
|
|
358
|
+
/* --- Toast + spinner --- */
|
|
359
|
+
#hold-hint { position: absolute; right: 36px; bottom: 20px; z-index: 20; font-size: 17px; color: #c7cbd4; background: rgba(0,0,0,0.6); padding: 6px 14px; border-radius: 16px; pointer-events: none; }
|
|
360
|
+
#toast { position: absolute; bottom: 60px; left: 50%; margin-left: -300px; width: 600px; text-align: center; z-index: 40; background: rgba(0,0,0,0.85); padding: 18px 24px; border-radius: 10px; font-size: 22px; }
|
|
361
|
+
#spinner { position: absolute; top: 0; left: 0; width: 1920px; height: 1080px; z-index: 50; display: flex; flex-direction: column; align-items: center; justify-content: center; background: rgba(0,0,0,0.3); }
|
|
362
|
+
/* status line under the spinner ("Opening stream at 1080p…"); empty when unused */
|
|
363
|
+
#spinner-msg { margin-top: 26px; font-size: 28px; color: #fff; text-shadow: 0 2px 6px #000; text-align: center; }
|
|
364
|
+
.spin { width: 70px; height: 70px; border: 7px solid rgba(255,255,255,0.2); border-top-color: #818cf8; border-radius: 50%; -webkit-animation: sp 0.9s linear infinite; animation: sp 0.9s linear infinite; }
|
|
365
|
+
@-webkit-keyframes sp { to { -webkit-transform: rotate(360deg); } }
|
|
366
|
+
@keyframes sp { to { transform: rotate(360deg); } }
|
|
367
|
+
|
|
368
|
+
/* Home top row: tab pills + Search + Settings on the left, StremioK logo on the right */
|
|
369
|
+
.home-header .tabbar-inline { display: flex; align-items: center; }
|
|
370
|
+
.tab-pill { display: inline-flex; align-items: center; font-size: 22px; padding: 8px 13px; margin-right: 6px; border-radius: 28px; background: #1a1f2b; color: #aeb6c4; border: 4px solid transparent; white-space: nowrap; }
|
|
371
|
+
.tab-ic { margin-left: 6px; font-size: 22px; }
|
|
372
|
+
.tab-pill.active { background: #2a3346; color: #fff; }
|
|
373
|
+
.tab-pill.focusable.focused { background: #818cf8; color: #0e1117; border-color: #fff; }
|
|
374
|
+
.home-header .hchip.active { background: #2a3346; color: #fff; opacity: 1; }
|
|
375
|
+
.row-empty { margin: 50px 60px; font-size: 26px; color: #8b93a3; }
|
|
376
|
+
|
|
377
|
+
/* --- Subtitle fonts (bundled; SIL Open Font License, see css/fonts/OFL-*.txt) ---
|
|
378
|
+
Latin, Latin-extended and Cyrillic subsets; unicode-range makes the webview
|
|
379
|
+
load only the files a subtitle needs. Other scripts fall back to the TV font. */
|
|
380
|
+
@font-face { font-family: 'SK Roboto'; font-style: normal; font-weight: 500; src: url(fonts/roboto-cyrillic.woff2) format('woff2'); unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
|
|
381
|
+
@font-face { font-family: 'SK Roboto'; font-style: normal; font-weight: 500; src: url(fonts/roboto-latin-ext.woff2) format('woff2'); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
|
|
382
|
+
@font-face { font-family: 'SK Roboto'; font-style: normal; font-weight: 500; src: url(fonts/roboto-latin.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
|
|
383
|
+
@font-face { font-family: 'SK Atkinson Hyperlegible'; font-style: normal; font-weight: 400; src: url(fonts/atkinson-latin-ext.woff2) format('woff2'); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
|
|
384
|
+
@font-face { font-family: 'SK Atkinson Hyperlegible'; font-style: normal; font-weight: 400; src: url(fonts/atkinson-latin.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
|
|
385
|
+
@font-face { font-family: 'SK Nunito'; font-style: normal; font-weight: 600; src: url(fonts/nunito-cyrillic.woff2) format('woff2'); unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
|
|
386
|
+
@font-face { font-family: 'SK Nunito'; font-style: normal; font-weight: 600; src: url(fonts/nunito-latin-ext.woff2) format('woff2'); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
|
|
387
|
+
@font-face { font-family: 'SK Nunito'; font-style: normal; font-weight: 600; src: url(fonts/nunito-latin.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
|
|
388
|
+
@font-face { font-family: 'SK Cousine'; font-style: normal; font-weight: 400; src: url(fonts/cousine-cyrillic.woff2) format('woff2'); unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
|
|
389
|
+
@font-face { font-family: 'SK Cousine'; font-style: normal; font-weight: 400; src: url(fonts/cousine-latin-ext.woff2) format('woff2'); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
|
|
390
|
+
@font-face { font-family: 'SK Cousine'; font-style: normal; font-weight: 400; src: url(fonts/cousine-latin.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
|
|
391
|
+
|
|
392
|
+
/* --- Appearance: color swatch in the accent picker --- */
|
|
393
|
+
.pick-item .swatch { display: inline-block; width: 24px; height: 24px; border-radius: 12px; margin-right: 16px; vertical-align: middle; border: 2px solid rgba(255,255,255,0.35); }
|
|
394
|
+
|
|
395
|
+
/* --- Title logos (instead of the title as text) --- */
|
|
396
|
+
.detail-title.has-logo { height: 84px; margin-bottom: 14px; }
|
|
397
|
+
.detail-logo { display: block; max-height: 84px; max-width: 560px; }
|
|
398
|
+
.series-body .detail-title.has-logo { height: 64px; margin-bottom: 8px; }
|
|
399
|
+
.series-body .detail-meta { margin-bottom: 12px; } /* (tighter: headroom for the TV's taller font above the buttons) */
|
|
400
|
+
.series-body .detail-logo { max-height: 64px; }
|
|
401
|
+
.detail-title.logo-failed { line-height: 84px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 1400px; }
|
|
402
|
+
.series-body .detail-title.logo-failed { line-height: 64px; }
|
|
403
|
+
.home-info-title { height: 36px; }
|
|
404
|
+
.home-info-logo { display: block; max-height: 36px; max-width: 520px; }
|
|
405
|
+
|
|
406
|
+
/* --- Ratings from MDBList --- */
|
|
407
|
+
.detail-ratings { font-size: 21px; line-height: 26px; height: 26px; color: #ffd257; margin: -6px 0 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 1400px; }
|
|
408
|
+
.detail-ratings:empty { display: none; }
|
|
409
|
+
.detail-ratings.reserve:empty { display: block; } /* ratings on their way: keep their line */
|
|
410
|
+
|
|
411
|
+
/* --- Cast & more / person pages --- */
|
|
412
|
+
.more-body { max-height: 290px; overflow: hidden; }
|
|
413
|
+
.more-body .detail-desc { max-height: 64px; margin-bottom: 0; }
|
|
414
|
+
.person-body { right: 360px; } /* clear of the photo */
|
|
415
|
+
.person-body .detail-desc { max-height: 128px; }
|
|
416
|
+
.ratings-body .detail-desc { display: none; }
|
|
417
|
+
/* full width like the Home rows: the row padding leaves room for the focused (scaled,
|
|
418
|
+
ringed) first card, which a panel starting at 60px would clip */
|
|
419
|
+
.more-panel { top: 440px; left: 0; right: 0; bottom: 0; }
|
|
420
|
+
.more-rows { position: absolute; top: 0; left: 0; right: 0; bottom: 0; overflow: hidden; }
|
|
421
|
+
.card.person-card { width: 150px; height: 225px; }
|
|
422
|
+
.card .cap .cap-name { font-weight: bold; }
|
|
423
|
+
.card .cap .cap-sub { font-size: 15px; color: #c7cbd4; }
|
|
424
|
+
.person-photo { position: absolute; top: 116px; right: 80px; width: 220px; height: 330px; border-radius: 12px; background-size: cover; background-position: center top; }
|
|
425
|
+
|
|
426
|
+
/* --- Episode ratings grid --- */
|
|
427
|
+
.grid-panel { top: 360px; bottom: 30px; }
|
|
428
|
+
.grid-scroll { position: absolute; top: 0; left: 0; right: 0; bottom: 40px; overflow: hidden; }
|
|
429
|
+
.grid-table .grid-row { white-space: nowrap; height: 52px; } /* (the episode ratings grid only: Home's Watching rows are .grid-row too) */
|
|
430
|
+
.grid-cell { display: inline-block; width: 76px; height: 44px; line-height: 38px; margin: 0 6px 8px 0; text-align: center; border-radius: 6px; font-size: 20px; font-weight: bold; vertical-align: top; border: 3px solid transparent; color: #fff; }
|
|
431
|
+
.grid-label { color: #8b93a5; }
|
|
432
|
+
.r-na { background: #1a1f2b; color: #6f7788; }
|
|
433
|
+
.r-9 { background: #15803d; }
|
|
434
|
+
.r-8 { background: #22a35a; }
|
|
435
|
+
.r-7 { background: #b89514; }
|
|
436
|
+
.r-6 { background: #c2621b; }
|
|
437
|
+
.r-5 { background: #b42318; }
|
|
438
|
+
.grid-cell.focusable.focused { border-color: #fff; }
|
|
439
|
+
.grid-legend { position: absolute; left: 0; bottom: 0; font-size: 18px; color: #8b93a5; }
|
|
440
|
+
|
|
441
|
+
/* --- Continue Watching: new episode --- */
|
|
442
|
+
.dl-list { margin: 6px 40px 18px 60px; max-width: 1500px; } /* (the Local tab's Downloads: lined up with the drives' grid) */
|
|
443
|
+
.dl-list .row-title { margin-left: 0; }
|
|
444
|
+
.dl-list .dl-item.done .a-name { color: #9ae6b4; }
|
|
445
|
+
.dl-list .dl-item.failed .a-name { color: #fbbf24; }
|
|
446
|
+
.rows .cal-watched { display: inline-block; min-width: 520px; margin: 22px 0 6px 0; } /* (the Calendar's Watched: OK shows it) */
|
|
447
|
+
.card .card-new.card-code { background: rgba(14, 17, 23, 0.85); color: #e6e9ef; } /* (the Calendar's episode / percentage tag) */
|
|
448
|
+
.card .card-new { position: absolute; top: 8px; left: 8px; z-index: 2; padding: 3px 10px; border-radius: 6px; background: #ef4444; color: #fff; font-size: 16px; font-weight: bold; }
|
|
449
|
+
|
|
450
|
+
/* --- Source list: quality group headings, Play best --- */
|
|
451
|
+
.stream-group { font-size: 22px; font-weight: bold; color: #c7cbd4; margin: 22px 0 10px 6px; }
|
|
452
|
+
.stream-group:first-child, .stream-for + .stream-group { margin-top: 4px; }
|
|
453
|
+
.no-sources { margin: 2px 0 14px 6px; }
|
|
454
|
+
.stream-note { margin: 0 0 14px 6px; max-width: 1500px; } /* an addon's "why" (AIOStreams' Removal Reasons…) */
|
|
455
|
+
.stream-note .sn-title { font-size: 22px; color: #e6e9ef; }
|
|
456
|
+
.stream-note .sn-text { font-size: 20px; color: #a7adba; margin-top: 4px; } /* "No sources found." above its Re-scan row */
|
|
457
|
+
.stream-for { font-size: 20px; color: #a7adba; margin: 2px 0 12px 6px; } /* "Sources for The Bear S2E1 · 1 more addon still loading…" */
|
|
458
|
+
|
|
459
|
+
/* --- Settings > Formats --- */
|
|
460
|
+
.formats-group { font-size: 22px; font-weight: bold; color: #c7cbd4; margin: 20px 0 10px 4px; }
|
|
461
|
+
.format-row.format-ok .a-name { color: #7ee2a8; }
|
|
462
|
+
.format-row.format-bad .a-name { color: #f0a5a5; }
|
|
463
|
+
.format-row.focusable.focused .a-name { color: inherit; }
|
|
464
|
+
|
|
465
|
+
/* --- Discover --- */
|
|
466
|
+
.discover-bar { position: absolute; top: 112px; left: 60px; right: 60px; white-space: nowrap; }
|
|
467
|
+
.discover-bar .pill { margin-right: 12px; }
|
|
468
|
+
.discover-search { width: 300px; margin-right: 12px; padding: 12px 22px; font-size: 22px; vertical-align: middle; background: #1a1f2b; color: #e6e9ef; border: 4px solid transparent; border-radius: 30px; }
|
|
469
|
+
.discover-search.focused { border-color: #818cf8; }
|
|
470
|
+
.discover-count { display: inline-block; margin-left: 14px; font-size: 20px; color: #8b93a5; vertical-align: middle; }
|
|
471
|
+
#screen-discover .home-info { top: 196px; height: 124px; }
|
|
472
|
+
#screen-discover .home-info-desc { max-height: 26px; }
|
|
473
|
+
.discover-grid { position: absolute; top: 330px; left: 0; right: 0; bottom: 0; overflow: hidden;
|
|
474
|
+
padding: 26px 40px 60px 60px; display: flex; flex-wrap: wrap; align-content: flex-start; overflow-anchor: none; } /* the app keeps its place when rows go (newer browsers would too: twice) */
|
|
475
|
+
.discover-grid .card { flex: 0 0 auto; margin: 0 22px 34px 0; }
|
|
476
|
+
.discover-grid .row-empty { margin: 30px 0; }
|
|
477
|
+
.discover-grid .discover-empty { flex: 0 0 100%; } /* an empty answer: its message, then ↻ Try again under it */
|
|
478
|
+
.discover-grid .discover-empty .row-empty { margin: 30px 0 22px 0; }
|
|
479
|
+
.discover-grid .discover-retry { display: inline-block; }
|
|
480
|
+
/* Continue Watching: the cards wrap into a grid (like Discover's), which the rows area scrolls */
|
|
481
|
+
.card-grid { display: flex; flex-wrap: wrap; align-content: flex-start; padding: 26px 40px 30px 60px; }
|
|
482
|
+
.card-grid .card { flex: 0 0 auto; margin: 0 22px 34px 0; }
|
|
483
|
+
/* Local tab (a USB drive): folders as plain tiles, a video with no poster by its name */
|
|
484
|
+
.card.local-folder { background: #1c2333; }
|
|
485
|
+
.card.local-folder .fallback { font-size: 24px; color: #c9cfdb; }
|
|
486
|
+
.card.local-video .fallback { font-size: 18px; word-break: break-word; }
|
|
487
|
+
|
|
488
|
+
/* Hide spoilers: an unwatched episode's still, blurred */
|
|
489
|
+
.ep-thumb.spoiler { -webkit-filter: blur(14px); filter: blur(14px); }
|
|
490
|
+
/* Direct links only: how many sources were left out */
|
|
491
|
+
.streams-hidden { font-size: 20px; color: #9aa3b5; margin: 4px 0 12px; }
|
|
492
|
+
/* Continue on phone: the QR in the player's menu */
|
|
493
|
+
.phone-qr { padding: 8px 4px 12px; }
|
|
494
|
+
.phone-qr-spot { text-align: center; margin-bottom: 10px; }
|
|
495
|
+
.phone-qr-spot canvas { display: inline-block; } /* (drawn at its own size: scaling blurs it on Tizen 3) */
|
|
496
|
+
/* QR dialogs: an addon's Share / Configure, Play a link from the phone */
|
|
497
|
+
.qr-box { width: 900px; }
|
|
498
|
+
.qr-spot { text-align: center; margin: 4px 0 14px; min-height: 40px; }
|
|
499
|
+
.qr-spot canvas { display: inline-block; }
|
|
500
|
+
.qr-link { font-size: 22px; color: #c7cbd4; text-align: center; word-break: break-all; margin-bottom: 10px; }
|
|
501
|
+
.qr-note { font-size: 20px; color: #9aa3b5; text-align: center; margin-bottom: 18px; line-height: 1.4; }
|
|
502
|
+
|
|
503
|
+
/* Where an addon came from (Settings › Addons): S Stremio, A AIOManager, C a configuration file */
|
|
504
|
+
.src-badge { display: inline-block; margin-left: 12px; padding: 1px 8px; border-radius: 6px; font-size: 18px; font-weight: bold; line-height: 1.3; color: #fff; vertical-align: middle; }
|
|
505
|
+
.src-s { background: #7b5bf5; }
|
|
506
|
+
.src-a { background: #0f9f8f; }
|
|
507
|
+
.src-c { background: #6b7280; }
|
package/icon.png
ADDED
|
Binary file
|
package/index.html
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=1920, height=1080, user-scalable=no">
|
|
6
|
+
<title>StremioK</title>
|
|
7
|
+
<link rel="stylesheet" href="css/style.css?v=2.0.0">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<!-- CSS-applied sentinel (kept off-screen); app.js waits for its width before rendering -->
|
|
11
|
+
<div id="css-sentinel" style="position:absolute;left:-9999px;top:0;height:1px;overflow:hidden;"></div>
|
|
12
|
+
<!-- AVPlay video plane (Tizen). Sits behind the UI; shown only during playback. -->
|
|
13
|
+
<object type="application/avplayer" id="av-player"></object>
|
|
14
|
+
<!-- HTML5 fallback for desktop/dev testing when webapis.avplay is absent -->
|
|
15
|
+
<video id="html5-player" playsinline></video>
|
|
16
|
+
|
|
17
|
+
<div id="app">
|
|
18
|
+
<div id="screen-home" class="screen"></div>
|
|
19
|
+
<div id="screen-discover" class="screen hidden"></div>
|
|
20
|
+
<div id="screen-detail" class="screen hidden"></div>
|
|
21
|
+
<div id="screen-search" class="screen hidden"></div>
|
|
22
|
+
<div id="screen-settings" class="screen hidden"></div>
|
|
23
|
+
<div id="screen-addaddon" class="screen hidden"></div>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<!-- Subtitle overlay (over the video plane, under the OSD) -->
|
|
27
|
+
<div id="subs" class="hidden"></div>
|
|
28
|
+
|
|
29
|
+
<!-- Player OSD overlay (over the video plane) -->
|
|
30
|
+
<div id="player-osd" class="hidden">
|
|
31
|
+
<div id="osd-title"></div>
|
|
32
|
+
<div id="osd-chapter" class="hidden"></div>
|
|
33
|
+
<div id="osd-bar"><div id="osd-progress"></div><div id="osd-sponsor"></div><div id="osd-chapters"></div><div id="osd-buffer"></div><div id="osd-scrub-range" class="hidden"></div><div id="osd-scrub" class="hidden"><div id="osd-scrub-time"></div></div></div>
|
|
34
|
+
<div id="osd-times"><span id="osd-cur">00:00</span><span class="osd-right"><span id="osd-tags"></span><span id="osd-dur">00:00</span></span></div>
|
|
35
|
+
<div id="osd-hint">OK: Play/Pause ←/→: Seek RETURN: Back</div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<!-- In-player menu (opened with DOWN during playback) -->
|
|
39
|
+
<div id="sub-menu" class="hidden"></div>
|
|
40
|
+
|
|
41
|
+
<!-- Contextual quick-action bar (opened with UP during playback) -->
|
|
42
|
+
<div id="player-bar" class="hidden"></div>
|
|
43
|
+
|
|
44
|
+
<!-- Skip intro/recap/credits prompt (TheIntroDB) -->
|
|
45
|
+
<div id="skip-prompt" class="hidden"></div>
|
|
46
|
+
|
|
47
|
+
<!-- Stream info overlay (player menu → Stream info) -->
|
|
48
|
+
<div id="stream-info" class="hidden"></div>
|
|
49
|
+
|
|
50
|
+
<div id="toast" class="hidden"></div>
|
|
51
|
+
<div id="spinner" class="hidden"><div class="spin"></div><div id="spinner-msg"></div></div>
|
|
52
|
+
|
|
53
|
+
<!-- Load order matters: polyfills -> util -> iptv -> data -> input -> tvapps -> player parts -> player -> ytplay -> view parts -> views -> app -->
|
|
54
|
+
<!-- ?v= busts the TV webview cache on every release (keep in sync with package.json) -->
|
|
55
|
+
<script src="js/polyfills.js?v=2.0.0"></script>
|
|
56
|
+
<script src="js/util.js?v=2.0.0"></script>
|
|
57
|
+
<script src="js/iptv.js?v=2.0.0"></script>
|
|
58
|
+
<script src="js/youtube.js?v=2.0.0"></script>
|
|
59
|
+
<script src="js/stremio.js?v=2.0.0"></script>
|
|
60
|
+
<script src="js/trakt.js?v=2.0.0"></script>
|
|
61
|
+
<script src="js/keys.js?v=2.0.0"></script>
|
|
62
|
+
<script src="js/focus.js?v=2.0.0"></script>
|
|
63
|
+
<script src="js/tvapps.js?v=2.0.0"></script>
|
|
64
|
+
<script src="js/player-core.js?v=2.0.0"></script>
|
|
65
|
+
<script src="js/player-store.js?v=2.0.0"></script>
|
|
66
|
+
<script src="js/player-lang.js?v=2.0.0"></script>
|
|
67
|
+
<script src="js/player-quality.js?v=2.0.0"></script>
|
|
68
|
+
<script src="js/player-subs.js?v=2.0.0"></script>
|
|
69
|
+
<script src="js/player-audio.js?v=2.0.0"></script>
|
|
70
|
+
<script src="js/player-controls.js?v=2.0.0"></script>
|
|
71
|
+
<script src="js/player.js?v=2.0.0"></script>
|
|
72
|
+
<script src="js/ytplay.js?v=2.0.0"></script>
|
|
73
|
+
<script src="js/local.js?v=2.0.0"></script>
|
|
74
|
+
<script src="js/downloads.js?v=2.0.0"></script>
|
|
75
|
+
<script src="js/stremio-account.js?v=2.0.0"></script>
|
|
76
|
+
<script src="js/view-core.js?v=2.0.0"></script>
|
|
77
|
+
<script src="js/view-home.js?v=2.0.0"></script>
|
|
78
|
+
<script src="js/view-detail.js?v=2.0.0"></script>
|
|
79
|
+
<script src="js/view-search.js?v=2.0.0"></script>
|
|
80
|
+
<script src="js/view-settings.js?v=2.0.0"></script>
|
|
81
|
+
<script src="js/view-discover.js?v=2.0.0"></script>
|
|
82
|
+
<script src="js/views.js?v=2.0.0"></script>
|
|
83
|
+
<script src="js/app.js?v=2.0.0"></script>
|
|
84
|
+
<script src="js/hubpreview.js?v=2.0.0"></script>
|
|
85
|
+
</body>
|
|
86
|
+
</html>
|