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 }