Recently Written · git

subplz-web

git clone https://github.com/equwal/subplz-web

Log | Files | Refs


frontend/style.css (14120 bytes)

1 :root {
2   --bg: #f7f7f9;
3   --panel: #ffffff;
4   --ink: #16161a;
5   --muted: #6b6b76;
6   --line: #e3e3e9;
7   --accent: #4f46e5;
8   --accent-ink: #ffffff;
9   --accent-soft: #eef0ff;
10   --ok: #0f8a5f;
11   --ok-soft: #e7f6ef;
12   --err: #c0392b;
13   --err-soft: #fdecea;
14   --warn: #9a6700;
15   --warn-soft: #fff6dd;
16   --radius: 14px;
17   --shadow: 0 1px 2px rgba(16, 16, 32, .05), 0 8px 24px rgba(16, 16, 32, .06);
18 }
19 
20 @media (prefers-color-scheme: dark) {
21   :root {
22     --bg: #0f1013;
23     --panel: #17181d;
24     --ink: #ececf1;
25     --muted: #9a9aa6;
26     --line: #2a2b33;
27     --accent: #7c74ff;
28     --accent-ink: #0f1013;
29     --accent-soft: #1e1f33;
30     --ok: #46d19a;
31     --ok-soft: #12241d;
32     --err: #ff8b7a;
33     --err-soft: #2a1714;
34     --warn: #e6bb4f;
35     --warn-soft: #2a2312;
36     --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px rgba(0, 0, 0, .35);
37   }
38 }
39 
40 * { box-sizing: border-box; }
41 
42 /* An author `display` rule beats the UA stylesheet's [hidden] rule, and several
43    panels below set display explicitly. Keep [hidden] authoritative. */
44 [hidden] { display: none !important; }
45 
46 body {
47   margin: 0;
48   background: var(--bg);
49   color: var(--ink);
50   font: 15px/1.55 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
51         "Helvetica Neue", Arial, "Noto Sans", "Noto Sans JP", sans-serif;
52   -webkit-font-smoothing: antialiased;
53 }
54 
55 main, .topbar, footer { max-width: 880px; margin: 0 auto; padding: 0 20px; }
56 
57 .topbar {
58   display: flex; align-items: center; justify-content: space-between;
59   gap: 16px; flex-wrap: wrap; padding-top: 32px; padding-bottom: 20px;
60 }
61 .brand { display: flex; align-items: center; gap: 14px; }
62 .logo { font-size: 34px; line-height: 1; }
63 h1 { font-size: 22px; margin: 0; letter-spacing: -.01em; }
64 .tagline { margin: 2px 0 0; color: var(--muted); font-size: 13.5px; }
65 
66 .quota {
67   font-size: 13px; padding: 7px 13px; border-radius: 999px;
68   background: var(--accent-soft); color: var(--accent);
69   border: 1px solid transparent; white-space: nowrap;
70 }
71 .quota.blocked { background: var(--warn-soft); color: var(--warn); }
72 
73 /* ---------- pitch ---------- */
74 .pitch { margin: 0 0 22px; }
75 .pitch p { margin: 0 0 12px; }
76 .uses { list-style: none; padding: 0; margin: 0 0 12px; display: grid; gap: 7px; }
77 .uses li {
78   font-size: 14px; color: var(--muted);
79   padding-left: 18px; position: relative;
80 }
81 .uses li::before {
82   content: ""; position: absolute; left: 3px; top: 9px;
83   width: 5px; height: 5px; border-radius: 50%; background: var(--accent);
84 }
85 .uses strong { color: var(--ink); font-weight: 600; }
86 
87 /* ---------- dropzone ---------- */
88 .dropzone {
89   border: 2px dashed var(--line);
90   border-radius: var(--radius);
91   background: var(--panel);
92   padding: 46px 24px;
93   text-align: center;
94   cursor: pointer;
95   transition: border-color .15s, background .15s, transform .15s;
96 }
97 .dropzone:hover, .dropzone:focus-visible { border-color: var(--accent); outline: none; }
98 .dropzone.drag {
99   border-color: var(--accent); background: var(--accent-soft);
100   transform: scale(1.008);
101 }
102 .dz-icon { color: var(--accent); }
103 .dz-icon svg { width: 44px; height: 44px; }
104 .dz-title { font-size: 17px; font-weight: 600; margin: 14px 0 4px; }
105 .dz-title em { font-style: normal; text-decoration: underline; text-underline-offset: 3px; }
106 .dz-sub { margin: 0 0 10px; color: var(--muted); font-size: 14px; }
107 .dz-formats { margin: 0; color: var(--muted); font-size: 12px; }
108 
109 .linkbtn {
110   background: none; border: none; padding: 0; font: inherit;
111   color: var(--accent); cursor: pointer; text-decoration: underline;
112 }
113 
114 /* ---------- staged files ---------- */
115 .staged { display: grid; gap: 10px; }
116 .slot { display: flex; align-items: center; gap: 12px; }
117 .slot-tick {
118   width: 20px; height: 20px; flex: none; border-radius: 50%;
119   border: 2px dashed var(--line);
120 }
121 .slot.filled .slot-tick {
122   border: none; background: var(--ok); position: relative;
123 }
124 .slot.filled .slot-tick::after {
125   content: ""; position: absolute; left: 7px; top: 3px;
126   width: 5px; height: 10px; border: solid var(--panel);
127   border-width: 0 2px 2px 0; transform: rotate(45deg);
128 }
129 .slot-body { flex: 1; min-width: 0; }
130 .slot-label {
131   font-size: 11.5px; color: var(--muted);
132   text-transform: uppercase; letter-spacing: .05em;
133 }
134 .slot-value { font-weight: 500; word-break: break-word; }
135 .slot:not(.filled) .slot-value { font-weight: 400; color: var(--muted); }
136 .slot-x {
137   background: none; border: none; color: var(--muted); cursor: pointer;
138   font-size: 20px; line-height: 1; padding: 0 4px;
139 }
140 .slot-x:hover { color: var(--err); }
141 .slot:not(.filled) .slot-x { visibility: hidden; }
142 
143 /* ---------- panels ---------- */
144 .panel {
145   margin-top: 18px; background: var(--panel); border: 1px solid var(--line);
146   border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow);
147 }
148 .panel h2 { margin: 0 0 14px; font-size: 16px; }
149 .error { border-color: var(--err); background: var(--err-soft); color: var(--err); }
150 
151 .uploading { display: flex; gap: 16px; align-items: center; }
152 .up-body { flex: 1; min-width: 0; }
153 .up-title { margin: 0 0 8px; font-weight: 600; }
154 
155 .spinner {
156   width: 26px; height: 26px; flex: none; border-radius: 50%;
157   border: 3px solid var(--line); border-top-color: var(--accent);
158   animation: spin .8s linear infinite;
159 }
160 @keyframes spin { to { transform: rotate(360deg); } }
161 
162 .bar {
163   height: 8px; background: var(--line); border-radius: 999px; overflow: hidden;
164 }
165 .bar-fill {
166   height: 100%; width: 0%; background: var(--accent);
167   border-radius: 999px; transition: width .35s ease;
168 }
169 
170 /* ---------- confirm ---------- */
171 .pairing { margin: 0 0 18px; display: grid; gap: 8px; }
172 .pairing > div { display: flex; gap: 12px; align-items: baseline; }
173 .pairing dt {
174   color: var(--muted); font-size: 12.5px; width: 88px; flex: none;
175   text-transform: uppercase; letter-spacing: .04em;
176 }
177 .pairing dd {
178   margin: 0; font-weight: 500; word-break: break-word; min-width: 0;
179 }
180 .pairing .meta { color: var(--muted); font-weight: 400; font-size: 13px; }
181 
182 .langrow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
183 .langrow label {
184   font-size: 12.5px; color: var(--muted);
185   text-transform: uppercase; letter-spacing: .04em; width: 88px; flex: none;
186 }
187 select {
188   font: inherit; padding: 8px 11px; border-radius: 9px;
189   border: 1px solid var(--line); background: var(--panel); color: var(--ink);
190   min-width: 230px;
191 }
192 .detected {
193   font-size: 12.5px; padding: 4px 10px; border-radius: 999px;
194   background: var(--ok-soft); color: var(--ok);
195 }
196 .detected.low { background: var(--warn-soft); color: var(--warn); }
197 #splitnote { margin: 10px 0 0; padding-left: 98px; }
198 
199 /* ---------- match check ---------- */
200 .match {
201   margin-top: 16px; padding: 12px 14px; border-radius: 10px;
202   background: var(--ok-soft); border: 1px solid transparent;
203 }
204 .match.marginal { background: var(--warn-soft); }
205 .match.poor { background: var(--err-soft); }
206 .match-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
207 .match-badge {
208   font-size: 11.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px;
209   text-transform: uppercase; letter-spacing: .05em; white-space: nowrap;
210   background: var(--ok); color: var(--panel);
211 }
212 .match.marginal .match-badge { background: var(--warn); }
213 .match.poor .match-badge { background: var(--err); }
214 .match.good { color: var(--ok); }
215 .match.marginal { color: var(--warn); }
216 .match.poor { color: var(--err); }
217 .match-warnings {
218   margin: 8px 0 0; padding-left: 18px; font-size: 13px; opacity: .9;
219 }
220 .match-warnings:empty { display: none; }
221 
222 .actions { display: flex; gap: 10px; margin-top: 20px; flex-wrap: wrap; }
223 
224 button.primary, button.ghost, .dl {
225   font: inherit; font-weight: 500; padding: 9px 17px;
226   border-radius: 9px; cursor: pointer; border: 1px solid transparent;
227 }
228 button.primary { background: var(--accent); color: var(--accent-ink); }
229 button.primary:hover { filter: brightness(1.08); }
230 button.primary:disabled { opacity: .55; cursor: not-allowed; filter: none; }
231 button.ghost { background: transparent; color: var(--muted); border-color: var(--line); }
232 button.ghost:hover { color: var(--ink); border-color: var(--muted); }
233 
234 /* ---------- jobs ---------- */
235 .section-title { font-size: 16px; margin: 30px 0 12px; }
236 .jobs { list-style: none; padding: 0; margin: 0; display: grid; gap: 12px; }
237 
238 .job {
239   background: var(--panel); border: 1px solid var(--line);
240   border-radius: var(--radius); padding: 16px 18px; box-shadow: var(--shadow);
241 }
242 .job-head {
243   display: flex; align-items: center; gap: 10px;
244   justify-content: space-between; flex-wrap: wrap;
245 }
246 .job-name { font-weight: 600; word-break: break-word; min-width: 0; }
247 .job-sub { color: var(--muted); font-size: 13px; margin-top: 2px; }
248 
249 .pill {
250   font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 999px;
251   text-transform: uppercase; letter-spacing: .05em; white-space: nowrap;
252 }
253 .pill.queued, .pill.draft { background: var(--accent-soft); color: var(--accent); }
254 .pill.running { background: var(--accent-soft); color: var(--accent); }
255 .pill.succeeded { background: var(--ok-soft); color: var(--ok); }
256 .pill.failed { background: var(--err-soft); color: var(--err); }
257 .pill.canceled { background: var(--line); color: var(--muted); }
258 
259 .job .bar { margin-top: 12px; }
260 .job-stage {
261   display: flex; justify-content: space-between; gap: 10px;
262   color: var(--muted); font-size: 12.5px; margin-top: 7px;
263 }
264 .job-err {
265   margin-top: 10px; padding: 10px 12px; border-radius: 9px;
266   background: var(--err-soft); color: var(--err); font-size: 13px;
267   white-space: pre-wrap; word-break: break-word;
268 }
269 .job-files { display: flex; gap: 8px; margin-top: 13px; flex-wrap: wrap; }
270 .dl {
271   text-decoration: none; background: var(--accent); color: var(--accent-ink);
272   display: inline-flex; align-items: center; gap: 7px; font-size: 13.5px;
273   padding: 8px 14px;
274 }
275 .dl:hover { filter: brightness(1.08); }
276 .dl-size { opacity: .7; font-size: 12px; font-weight: 400; }
277 .dl.secondary { background: transparent; color: var(--muted); border-color: var(--line); }
278 .dl.secondary:hover { color: var(--ink); border-color: var(--muted); }
279 
280 /* ---------- the running job ---------- */
281 .working .up-title { margin: 0 0 10px; font-weight: 600; }
282 .working .job-files { margin-top: 16px; }
283 button.dl { font: inherit; font-weight: 500; cursor: pointer; border: 1px solid transparent; border-radius: 9px; }
284 button.dl:disabled { opacity: .6; cursor: progress; }
285 .bar.indeterminate .bar-fill { width: 35% !important; animation: slide 1.4s ease-in-out infinite; }
286 @keyframes slide { 0% { margin-left: -35%; } 100% { margin-left: 100%; } }
287 @media (prefers-reduced-motion: reduce) { .bar.indeterminate .bar-fill { animation: none; margin-left: 0; } }
288 
289 /* ---------- account bar ---------- */
290 .account { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
291 .who { color: var(--muted); font-size: 13px; max-width: 220px;
292        overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
293 button.compact { padding: 6px 12px; font-size: 13px; }
294 
295 /* ---------- tags ---------- */
296 .tag {
297   font-size: 10.5px; font-weight: 700; letter-spacing: .06em;
298   text-transform: uppercase; padding: 2px 7px; border-radius: 999px;
299   vertical-align: 1px; white-space: nowrap;
300 }
301 .tag.free { background: var(--ok-soft); color: var(--ok); }
302 
303 .mode { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 14px; }
304 .switch { display: flex; align-items: center; gap: 10px; cursor: pointer; }
305 .switch input { width: 18px; height: 18px; margin: 0; accent-color: var(--ok); flex: none; }
306 .switch input:disabled + span { color: var(--muted); }
307 
308 .share-form { display: grid; gap: 6px; margin: 14px 0 8px; }
309 .share-form label { font-size: 13px; font-weight: 600; margin-top: 6px; }
310 .share-form input { padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font: inherit; background: transparent; color: inherit; }
311 .share-form button { margin-top: 10px; }
312 
313 /* ---------- dialogs ---------- */
314 dialog.modal {
315   border: 1px solid var(--line); border-radius: var(--radius);
316   background: var(--panel); color: var(--ink); box-shadow: var(--shadow);
317   padding: 26px 26px 22px; width: min(420px, calc(100vw - 32px));
318 }
319 dialog.modal.wide { width: min(760px, calc(100vw - 32px)); }
320 dialog.modal::backdrop { background: rgba(10, 10, 20, .55); }
321 dialog.modal h2 { margin: 0 0 8px; font-size: 19px; }
322 .modal-x {
323   position: absolute; top: 10px; right: 12px; border: 0; background: none;
324   color: var(--muted); font-size: 24px; line-height: 1; cursor: pointer;
325 }
326 .modal-x:hover { color: var(--ink); }
327 
328 .signin-form { display: flex; gap: 8px; margin: 16px 0 10px; flex-wrap: wrap; }
329 .signin-form input {
330   flex: 1; min-width: 200px; font: inherit; padding: 9px 12px;
331   border-radius: 9px; border: 1px solid var(--line);
332   background: var(--bg); color: var(--ink);
333 }
334 .signin-form input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
335 
336 .plans {
337   display: grid; gap: 12px; margin: 18px 0 16px;
338   grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
339 }
340 .plan {
341   border: 1px solid var(--line); border-radius: 12px; padding: 16px 14px;
342   display: flex; flex-direction: column; gap: 4px;
343 }
344 .plan.featured { border-color: var(--accent); }
345 .plan-name { font-weight: 600; }
346 .plan-price { font-size: 24px; font-weight: 700; letter-spacing: -.01em; }
347 .plan-price small { font-size: 13px; font-weight: 400; color: var(--muted); }
348 .plan-per { font-size: 12.5px; color: var(--ok); }
349 .plan-blurb { color: var(--muted); font-size: 13px; margin: 4px 0 12px; flex: 1; }
350 .plan button { width: 100%; }
351 
352 .toast {
353   position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
354   background: var(--ink); color: var(--bg); padding: 11px 18px;
355   border-radius: 10px; box-shadow: var(--shadow); font-size: 14px;
356   max-width: calc(100vw - 32px); z-index: 10;
357 }
358 
359 footer { padding-top: 34px; padding-bottom: 40px; }
360 footer a { color: var(--accent); }
361 .muted { color: var(--muted); }
362 .small { font-size: 12.5px; }
363 
364 @media (max-width: 560px) {
365   .pairing dt, .langrow label { width: 100%; }
366   .pairing > div { flex-direction: column; gap: 2px; }
367   #splitnote { padding-left: 0; }
368   select { min-width: 0; width: 100%; }
369 }