draw things doodl.waow.tech
draw atproto
0

Configure Feed

Select the types of activity you want to include in your feed.

doodl / src / style.css
27 kB 918 lines
1:root { 2 --bg: #fafaf8; 3 --ink: #111; 4 --line: #e2e2dd; 5 --surface: #fff; 6 --muted: #888; 7 --hover: #f3f3ef; 8 --accent: #3b5bdb; 9 font-family: ui-monospace, "SF Mono", Menlo, monospace; 10 color-scheme: light; 11} 12 13:root[data-theme="dark"] { 14 --bg: #15151a; 15 --ink: #e9e9ee; 16 --line: #2c2c34; 17 --surface: #1e1e25; 18 --muted: #8a8a96; 19 --hover: #2a2a31; 20 --accent: #5c7cfa; 21 color-scheme: dark; 22} 23 24* { box-sizing: border-box; } 25 26/* the hidden attribute must win over the id selectors' display rules below */ 27[hidden] { display: none !important; } 28 29html, body { height: 100%; } 30 31button, 32a, 33input { 34 touch-action: manipulation; 35} 36 37body { 38 margin: 0; 39 background: var(--bg); 40 color: var(--ink); 41 /* mobile-first: full-height app shell, no page scroll on the draw view */ 42 display: flex; 43 flex-direction: column; 44 min-height: 100dvh; 45 overscroll-behavior: none; 46 /* no double-tap-to-zoom (e.g. rapid undo); canvas overrides with none */ 47 touch-action: manipulation; 48 -webkit-text-size-adjust: 100%; 49} 50 51/* ---- header ---- */ 52header { 53 display: flex; 54 align-items: center; 55 gap: 1rem; 56 padding: max(.75rem, env(safe-area-inset-top)) 1rem .75rem; 57 border-bottom: 1px solid var(--line); 58 flex-wrap: wrap; 59} 60h1 { margin: 0; font-size: 1.05rem; font-weight: 600; } 61 62nav { display: flex; align-items: center; gap: .25rem; } 63nav button { 64 min-height: 44px; 65 background: none; 66 border: none; 67 cursor: pointer; 68 font: inherit; 69 color: var(--muted); 70 padding: .35rem .55rem; 71} 72nav button.active { color: var(--ink); border-bottom: 2px solid var(--accent); } 73 74#session { margin-left: auto; font-size: .8rem; color: var(--muted); } 75#session a { color: var(--accent); cursor: pointer; } 76 77/* ---- login typeahead ---- */ 78.login { position: relative; } 79.login input { 80 font: inherit; 81 font-size: 1rem; 82 min-height: 44px; 83 padding: .55rem .7rem; 84 border: 1px solid var(--line); 85 border-radius: 8px; 86 width: 100%; 87} 88/* the handle picker drops the trigger button for an input; on mobile it can't 89 share the header line with the title + nav without overflowing, so give it 90 its own full-width row instead of letting it wrap into a cramped partial one */ 91.trigger-wrap:has(.login) { flex-basis: 100%; margin-left: 0; } 92.trigger-wrap .login { width: 100%; } 93#handle-suggestions { 94 position: absolute; 95 right: 0; 96 top: 100%; 97 margin: .25rem 0 0; 98 padding: .25rem; 99 list-style: none; 100 background: var(--surface); 101 border: 1px solid var(--line); 102 border-radius: 8px; 103 box-shadow: 0 6px 18px rgba(0, 0, 0, .1); 104 min-width: 240px; 105 max-height: 50vh; 106 overflow-y: auto; 107 z-index: 20; 108} 109#handle-suggestions li { 110 display: flex; 111 align-items: center; 112 gap: .5rem; 113 min-height: 44px; 114 padding: .55rem; 115 border-radius: 6px; 116 cursor: pointer; 117} 118#handle-suggestions li:active, 119#handle-suggestions li:hover { background: var(--hover); } 120#handle-suggestions img { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; } 121 122/* ---- main / draw view ---- */ 123main { flex: 1; display: flex; flex-direction: column; min-height: 0; } 124 125#view-draw { 126 flex: 1; 127 display: flex; 128 flex-direction: column; 129 min-height: 0; 130 padding: .75rem; 131 gap: .6rem; 132} 133 134/* ---- toolbar ---- */ 135.tools { 136 display: flex; 137 align-items: center; 138 gap: .5rem; 139 flex-wrap: wrap; 140} 141.spacer { flex: 1; } 142 143/* ---- color + stroke pickers: compact square trigger buttons; the swatches 144 and slider they used to spread across the toolbar now live in popups ---- */ 145.tool-actions .picker-btn { 146 padding: 0; 147 width: 44px; 148 flex: 0 0 44px; 149} 150/* the color trigger previews the current color as a filled swatch */ 151#color-btn::after { 152 content: ""; 153 width: 24px; 154 height: 24px; 155 border-radius: 50%; 156 background: var(--c, #1c7ed6); 157 box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .18); 158} 159 160/* ---- color popup: the full palette + custom picker, roomy 44px targets ---- */ 161.color-panel { 162 display: flex; 163 flex-wrap: wrap; 164 justify-content: center; 165 gap: .6rem; 166 padding: .25rem .25rem 1.25rem; 167} 168.swatch { 169 flex: 0 0 auto; 170 width: 44px; 171 height: 44px; 172 padding: 0; 173 border: 2px solid #fff; 174 border-radius: 50%; 175 box-shadow: 0 0 0 1px var(--line); 176 cursor: pointer; 177} 178.swatch.sel { box-shadow: 0 0 0 2px var(--ink); } 179 180/* custom picker: rainbow ring around the current custom color */ 181.swatch.custom { 182 display: inline-flex; 183 align-items: center; 184 justify-content: center; 185 background: conic-gradient(from 0deg, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00); 186 border-color: #fff; 187} 188.swatch.custom input[type="color"] { 189 width: 28px; 190 height: 28px; 191 padding: 0; 192 border: 2px solid #fff; 193 border-radius: 50%; 194 background: none; 195 cursor: pointer; 196 -webkit-appearance: none; 197 appearance: none; 198} 199.swatch.custom input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; } 200.swatch.custom input[type="color"]::-webkit-color-swatch { border: none; border-radius: 50%; } 201.swatch.custom input[type="color"]::-moz-color-swatch { border: none; border-radius: 50%; } 202 203/* ---- stroke: a toolbar button previewing the current width as a dot; 204 tapping it opens the stroke popup (width slider + room for future styles) ---- */ 205.picker-btn { display: inline-flex; align-items: center; justify-content: center; } 206.brush-dot { 207 flex: 0 0 26px; 208 width: 26px; 209 height: 26px; 210 display: inline-flex; 211 align-items: center; 212 justify-content: center; 213} 214.brush-dot::after { 215 content: ""; 216 width: var(--d, 8px); 217 height: var(--d, 8px); 218 border-radius: 50%; 219 background: var(--ink); 220} 221/* ---- stroke popup body ---- */ 222.stroke-panel { 223 display: flex; 224 align-items: center; 225 gap: 1rem; 226 padding: .25rem .25rem 1rem; 227} 228#stroke-range { 229 flex: 1; 230 -webkit-appearance: none; 231 appearance: none; 232 width: 100%; 233 height: 44px; 234 background: transparent; 235 cursor: pointer; 236} 237/* track */ 238#stroke-range::-webkit-slider-runnable-track { 239 height: 6px; 240 border-radius: 3px; 241 background: var(--line); 242} 243#stroke-range::-moz-range-track { height: 6px; border-radius: 3px; background: var(--line); } 244/* thumb — large for touch */ 245#stroke-range::-webkit-slider-thumb { 246 -webkit-appearance: none; 247 appearance: none; 248 width: 26px; 249 height: 26px; 250 margin-top: -10px; 251 border-radius: 50%; 252 background: var(--accent); 253 border: 2px solid var(--surface); 254 box-shadow: 0 1px 3px rgba(0, 0, 0, .25); 255} 256#stroke-range::-moz-range-thumb { 257 width: 26px; 258 height: 26px; 259 border-radius: 50%; 260 background: var(--accent); 261 border: 2px solid var(--surface); 262 box-shadow: 0 1px 3px rgba(0, 0, 0, .25); 263} 264 265/* undo / clear / save — grouped so they wrap together, never split apart */ 266.tool-actions { display: flex; align-items: center; gap: .5rem; } 267.tool-actions button { 268 font: inherit; 269 border: 1px solid var(--line); 270 background: var(--surface); 271 padding: .55rem .8rem; 272 border-radius: 10px; 273 cursor: pointer; 274 min-height: 44px; 275} 276.tool-actions button:disabled { opacity: .5; cursor: not-allowed; } 277#save:not(:disabled) { background: var(--accent); color: #fff; border-color: var(--accent); } 278 279/* ---- canvas fills remaining space as a large centered square ---- */ 280.canvas-wrap { 281 flex: 1; 282 min-height: 0; 283 display: flex; 284 align-items: center; 285 justify-content: center; 286} 287#pad { 288 /* square as large as the shorter available dimension allows. color + stroke 289 are popups now, so the toolbar is a single row — the canvas claims the 290 space the old swatch/slider rows used to take. (max-height:100% below still 291 guards against vertical overflow.) */ 292 width: min(100%, calc(100dvh - 150px)); 293 height: auto; 294 aspect-ratio: 1; 295 max-height: 100%; 296 border: 1px solid var(--line); 297 border-radius: 12px; 298 background: #fff; 299 touch-action: none; 300 cursor: crosshair; 301 box-shadow: 0 1px 3px rgba(0, 0, 0, .04); 302} 303 304#status { font-size: .85rem; color: var(--muted); min-height: 1.2em; margin: 0; text-align: center; } 305#status .cheer { color: var(--ink); font-weight: 600; } 306.saved-actions { display: inline-flex; gap: .4rem; margin-left: .5rem; vertical-align: middle; } 307.pill { 308 font: inherit; 309 font-size: .85rem; 310 min-height: 44px; 311 padding: .5rem .8rem; 312 border-radius: 999px; 313 border: 1px solid var(--line); 314 background: var(--surface); 315 color: var(--ink); 316 text-decoration: none; 317 cursor: pointer; 318 display: inline-flex; 319 align-items: center; 320 justify-content: center; 321} 322.pill:hover { background: var(--hover); } 323#status .pill { font-size: .78rem; } 324#status.pop .cheer { display: inline-block; animation: pop .45s cubic-bezier(.2, 1.4, .4, 1); } 325@keyframes pop { 326 0% { transform: scale(.7); opacity: 0; } 327 60% { transform: scale(1.12); opacity: 1; } 328 100% { transform: scale(1); } 329} 330 331/* ---- explore ---- */ 332/* scroll within main so the footer stays pinned (was: tall gallery overflowed 333 main and overlapped the footer) */ 334#view-explore { flex: 1; min-height: 0; overflow-y: auto; padding: 1rem; } 335.hint { font-size: .85rem; color: var(--muted); } 336#gallery { 337 display: grid; 338 grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); 339 gap: .75rem; 340} 341.card { 342 position: relative; 343 border: 1px solid var(--line); 344 border-radius: 12px; 345 background: var(--surface); 346 padding: .5rem; 347 text-align: center; 348 cursor: pointer; 349} 350.card:hover { border-color: var(--muted); } 351.card-img { width: 100%; aspect-ratio: 1; object-fit: contain; } 352.card .who { font-size: .72rem; color: var(--muted); margin-top: .4rem; word-break: break-all; } 353 354/* a remix reads as such at a glance: a quiet accent-tinted edge + a credit to 355 the original artist, marked with your own drawn remix glyph (a slot) */ 356.card.remix { border-color: color-mix(in srgb, var(--accent) 32%, var(--line)); } 357.card.remix:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); } 358.remix-credit { 359 display: inline-flex; align-items: center; gap: .25rem; max-width: 100%; 360 margin-top: .15rem; font-size: .66rem; color: var(--muted); text-decoration: none; 361} 362.remix-credit:hover { color: var(--accent); } 363.remix-credit .slot-img { height: 1.15em; width: auto; } 364 365/* avatar tucked in the top-left, always visible, out of the way */ 366.card-ava { 367 position: absolute; 368 top: .4rem; 369 left: .4rem; 370 width: 22px; 371 height: 22px; 372 border-radius: 50%; 373 object-fit: cover; 374 background: var(--hover); 375 display: inline-flex; 376 align-items: center; 377 justify-content: center; 378 font-size: .65rem; 379 font-weight: 600; 380 color: var(--muted); 381 border: 1px solid var(--surface); 382} 383 384/* subtle corner actions, top-right — never cover the handle */ 385.card-actions { 386 position: absolute; 387 top: .3rem; 388 right: .3rem; 389 display: flex; 390 gap: .25rem; 391 opacity: 0; 392 transition: opacity .12s; 393} 394.card:hover .card-actions, .card:focus-within .card-actions { opacity: 1; } 395@media (hover: none) { .card-actions { opacity: .9; } } 396.ca-btn { 397 width: 26px; 398 height: 26px; 399 display: inline-flex; 400 align-items: center; 401 justify-content: center; 402 border: 1px solid var(--line); 403 border-radius: 8px; 404 background: color-mix(in srgb, var(--surface) 80%, transparent); 405 backdrop-filter: blur(3px); 406 color: var(--muted); 407 font-size: .72rem; 408 line-height: 1; 409 cursor: pointer; 410} 411.ca-btn:hover { color: var(--ink); background: var(--surface); } 412.ca-btn.danger:hover { color: #e03131; } 413.ca-btn:disabled { opacity: .4; cursor: wait; } 414 415/* ---- per-drawing display page ---- */ 416.display { 417 max-width: 560px; 418 margin: 0 auto; 419 padding: 1.5rem; 420 display: flex; 421 flex-direction: column; 422 gap: 1rem; 423 align-items: center; 424} 425.display .back { align-self: flex-start; color: var(--accent); text-decoration: none; font-size: .9rem; } 426.display-card { width: 100%; text-align: center; } 427.display-img { 428 width: 100%; 429 max-width: 420px; 430 aspect-ratio: 1; 431 object-fit: contain; 432 border: 1px solid var(--line); 433 border-radius: 16px; 434 background: #fff; 435} 436.display-by { color: var(--muted); font-size: .95rem; } 437.display-by strong { color: var(--ink); } 438.remix-of { display: inline-flex; align-items: center; gap: .45rem; color: var(--muted); font-size: .9rem; } 439.remix-of:hover { color: var(--accent); } 440.remix-of-thumb { height: 2.2em; width: 2.2em; object-fit: contain; border: 1px solid var(--line); border-radius: 7px; background: #fff; } 441.remix-original { margin: -.25rem 0 0; font-size: .82rem; color: var(--muted); } 442.remix-original a { color: var(--accent); } 443/* remixes of THIS drawing — overlapping clickable thumbnails (plyr likers-stack) */ 444.remixes { display: inline-flex; align-items: center; gap: .6rem; flex-wrap: wrap; justify-content: center; } 445.remix-count { color: var(--muted); font-size: .9rem; } 446.remix-stack { display: inline-flex; } 447.remix-chip { 448 width: 40px; height: 40px; border-radius: 10px; 449 border: 2px solid var(--surface); box-shadow: 0 0 0 1px var(--line); 450 background: #fff; overflow: hidden; margin-left: -10px; 451 display: inline-flex; align-items: center; justify-content: center; position: relative; 452 transition: transform .2s cubic-bezier(.34, 1.56, .64, 1); 453} 454.remix-chip:first-child { margin-left: 0; } 455.remix-chip:hover { transform: translateY(-3px) scale(1.1); z-index: 10; } 456.remix-chip img { width: 100%; height: 100%; object-fit: contain; } 457.remix-chip span { font-size: .6rem; color: var(--muted); } 458.remix-more { color: var(--muted); font-size: .85rem; } 459.display-actions { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; } 460.display-actions a { 461 min-height: 44px; 462 display: inline-flex; 463 align-items: center; 464 color: var(--accent); 465 text-decoration: none; 466 font-size: .9rem; 467} 468/* the primary call to action — remixing is the point */ 469.display-actions a.remix { 470 order: -1; 471 flex-basis: 100%; 472 justify-content: center; 473 background: var(--accent); 474 color: #fff; 475 border-radius: 10px; 476 padding: 0 1.25rem; 477 font-size: 1rem; 478 font-weight: 600; 479} 480 481/* ---- mode banner (e.g. drawing an icon) ---- */ 482.mode-banner { 483 display: flex; 484 align-items: center; 485 gap: .5rem; 486 flex-wrap: wrap; 487 font-size: .85rem; 488 color: var(--ink); 489 background: var(--hover); 490 border: 1px solid var(--line); 491 border-radius: 10px; 492 padding: .5rem .75rem; 493} 494 495/* ---- account / settings menu ---- */ 496.menu { margin-left: auto; position: relative; } 497 498/* draw-your-own-icon row in the menu */ 499.icon-row { 500 display: flex; 501 align-items: center; 502 gap: .5rem; 503 width: 100%; 504 font: inherit; 505 font-size: .85rem; 506 text-align: left; 507 border: none; 508 background: none; 509 color: var(--ink); 510 padding: .4rem; 511 border-radius: 7px; 512 cursor: pointer; 513} 514.icon-row:hover { background: var(--hover); } 515.icon-row img { 516 width: 30px; 517 height: 30px; 518 object-fit: contain; 519} 520/* the trigger is just the drawing itself — no circle, no frame */ 521.menu-trigger { 522 position: relative; 523 display: inline-flex; 524 align-items: center; 525 border: none; 526 background: none; 527 cursor: pointer; 528 padding: .25rem .4rem; 529 font: inherit; 530 color: var(--muted); 531} 532.menu-trigger:hover { color: var(--ink); } 533.menu-icon { 534 width: 44px; 535 height: 44px; 536 object-fit: contain; 537 display: block; 538} 539/* signed-in badge tucked in the corner */ 540.menu-trigger .dot.on { 541 position: absolute; 542 right: -2px; 543 bottom: -2px; 544 width: 10px; 545 height: 10px; 546 border-radius: 50%; 547 background: #2f9e44; 548 border: 2px solid var(--bg); 549} 550.menu-pop { 551 position: absolute; 552 right: 0; 553 top: calc(100% + .4rem); 554 min-width: 180px; 555 background: var(--surface); 556 border: 1px solid var(--line); 557 border-radius: 12px; 558 box-shadow: 0 8px 24px rgba(0, 0, 0, .14); 559 padding: .5rem; 560 z-index: 30; 561} 562.menu-account { display: flex; flex-direction: column; gap: .25rem; } 563.menu-handle { font-size: .8rem; color: var(--muted); padding: .25rem .4rem; word-break: break-all; } 564.menu-item { 565 font: inherit; 566 text-align: left; 567 border: none; 568 background: none; 569 color: var(--ink); 570 padding: .45rem .4rem; 571 border-radius: 7px; 572 cursor: pointer; 573} 574.menu-item:hover { background: var(--hover); } 575.menu-sep { height: 1px; background: var(--line); margin: .5rem 0; } 576.menu-label { font-size: .7rem; color: var(--muted); padding: 0 .4rem; } 577.seg { 578 display: flex; 579 gap: 2px; 580 margin-top: .35rem; 581 padding: 2px; 582 background: var(--hover); 583 border-radius: 8px; 584} 585.seg button { 586 flex: 1; 587 font: inherit; 588 font-size: .75rem; 589 border: none; 590 background: none; 591 color: var(--muted); 592 padding: .35rem; 593 border-radius: 6px; 594 cursor: pointer; 595} 596.seg button.sel { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(0, 0, 0, .12); } 597 598/* ---- footer ---- */ 599footer { 600 padding: 1rem; 601 border-top: 1px solid var(--line); 602 font-size: .78rem; 603 color: var(--muted); 604 text-align: center; 605} 606footer a { 607 color: inherit; 608 text-decoration: none; 609 border-bottom: 1px solid transparent; 610 transition: border-color .12s, color .12s; 611} 612footer a:hover { color: var(--ink); border-bottom-color: var(--muted); } 613 614/* ---- desktop: give the canvas room, roomier chrome ---- */ 615@media (min-width: 720px) { 616 header { padding: 1rem 1.5rem; gap: 1.5rem; } 617 h1 { font-size: 1.1rem; } 618 h1 .slot-img { height: 48px; } 619 nav .slot-img { height: 40px; } 620 /* desktop has room — keep the handle picker inline, right-aligned */ 621 .trigger-wrap:has(.login) { flex-basis: auto; margin-left: auto; } 622 .trigger-wrap .login { width: auto; } 623 .login input { width: 240px; } 624 #view-draw { padding: 1.25rem 1.5rem; gap: 1rem; } 625 #pad { width: min(100%, calc(100dvh - 140px)); } 626 #gallery { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); } 627} 628 629/* ---- settings view (full screen, mobile-first) ---- */ 630#view-settings { flex: 1; min-height: 0; overflow-y: auto; padding: 1rem; } 631.settings { max-width: 640px; margin: 0 auto; } 632.settings-bar { 633 display: flex; 634 align-items: center; 635 justify-content: space-between; 636 margin-bottom: 1.25rem; 637 padding-bottom: .75rem; 638 border-bottom: 1px solid var(--line); 639} 640.settings-bar h2 { margin: 0; font-size: 1.2rem; } 641.set-sec { margin-bottom: 1.75rem; } 642.set-sec h3 { 643 margin: 0 0 .6rem; 644 font-size: .8rem; 645 font-weight: 600; 646 color: var(--muted); 647 text-transform: lowercase; 648} 649.acct-handle { font-size: .95rem; margin-bottom: .6rem; word-break: break-all; } 650.set-btn { 651 font: inherit; 652 min-height: 48px; 653 padding: 0 1.1rem; 654 border: 1px solid var(--line); 655 border-radius: 12px; 656 background: var(--surface); 657 color: var(--ink); 658 cursor: pointer; 659} 660.set-btn:hover { background: var(--hover); } 661 662.theme-row { display: flex; gap: .5rem; } 663.theme-opt { 664 flex: 1; 665 min-height: 76px; 666 display: flex; 667 flex-direction: column; 668 align-items: center; 669 justify-content: center; 670 gap: .35rem; 671 font: inherit; 672 font-size: .8rem; 673 border: 1px solid var(--line); 674 border-radius: 14px; 675 background: var(--surface); 676 color: var(--ink); 677 cursor: pointer; 678} 679.theme-opt.sel { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); } 680.theme-opt img { width: 30px; height: 30px; object-fit: contain; } 681 682.slot-grid { 683 display: grid; 684 grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); 685 gap: .75rem; 686} 687.slot { 688 aspect-ratio: 1; 689 display: flex; 690 flex-direction: column; 691 align-items: center; 692 justify-content: center; 693 gap: .4rem; 694 font: inherit; 695 border: 1px solid var(--line); 696 border-radius: 16px; 697 background: var(--surface); 698 color: var(--ink); 699 cursor: pointer; 700} 701.slot:hover { background: var(--hover); } 702.slot img { width: 46px; height: 46px; object-fit: contain; } 703.slot-label { font-size: .72rem; color: var(--muted); } 704.ph { 705 display: inline-flex; 706 align-items: center; 707 justify-content: center; 708 width: 30px; 709 height: 30px; 710 border-radius: 8px; 711 background: var(--hover); 712 font-weight: 600; 713 color: var(--muted); 714} 715 716/* ---- bottom-sheet icon picker (native-app feel) ---- */ 717.sheet { 718 position: fixed; 719 inset: 0; 720 z-index: 50; 721 display: flex; 722 align-items: flex-end; 723 justify-content: center; 724 background: rgba(0, 0, 0, .45); 725} 726.sheet-card { 727 width: 100%; 728 max-width: 640px; 729 max-height: 82vh; 730 overflow-y: auto; 731 background: var(--surface); 732 border-radius: 20px 20px 0 0; 733 padding: .75rem 1rem calc(1rem + env(safe-area-inset-bottom)); 734 box-shadow: 0 -8px 30px rgba(0, 0, 0, .25); 735 animation: sheet-up .22s cubic-bezier(.2, .9, .3, 1); 736} 737@keyframes sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } } 738/* the grab handle only makes sense on touch (it's a swipe affordance) */ 739.sheet-grab { display: none; } 740@media (hover: none) and (pointer: coarse) { 741 .sheet-grab { 742 display: block; 743 width: 40px; 744 height: 4px; 745 border-radius: 2px; 746 background: var(--line); 747 margin: 0 auto .75rem; 748 } 749} 750.sheet-head { 751 display: flex; 752 align-items: center; 753 justify-content: space-between; 754 margin-bottom: .9rem; 755} 756.sheet-grid { 757 display: grid; 758 grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); 759 gap: .6rem; 760} 761.sheet-item, .sheet-new { 762 aspect-ratio: 1; 763 border-radius: 14px; 764 cursor: pointer; 765 padding: .4rem; 766} 767.sheet-item { 768 border: 1px solid var(--line); 769 background: var(--surface); 770} 771.sheet-item img { width: 100%; height: 100%; object-fit: contain; } 772.sheet-new { 773 display: flex; 774 flex-direction: column; 775 align-items: center; 776 justify-content: center; 777 gap: .25rem; 778 border: 2px dashed var(--line); 779 background: none; 780 color: var(--accent); 781 font: inherit; 782 font-size: .8rem; 783} 784.sheet-new span:first-child { font-size: 1.4rem; line-height: 1; } 785 786/* ---- slot images in their various live contexts ---- */ 787/* a drawn icon is a PICTURE, not a glyph: it carries far more spatial detail 788 than a letterform AND rarely fills its square canvas (a freehand mark might 789 occupy ~60% of it), so the *visible* drawing ends up ~half its box. sizing 790 one to text height (1em) is the recurring bug that makes drawings illegible — 791 same root cause as the favicon. interactive contexts (nav/menu/toolbar) are 792 ≥44px touch targets anyway, so let the drawing fill that box rather than 793 shrink to text height. base stays text-relative only for true inline use. */ 794.slot-img { height: 1.4em; width: auto; object-fit: contain; vertical-align: middle; } 795.menu-trigger .slot-img { width: 44px; height: 44px; object-fit: contain; display: block; } 796nav .slot-img { height: 34px; } 797.set-btn .slot-img { height: 1.6em; } 798.tool-actions button .slot-img { height: 30px; } 799.sheet-new .slot-img { width: 70%; height: 70%; } 800 801/* ---- sheet header actions ---- */ 802.sheet-head-actions { display: inline-flex; gap: .4rem; } 803 804/* the title wordmark as a slot: the brand mark, so it leads the header at a 805 clearly legible size rather than tracking the (small) heading font. */ 806h1 .slot-img { height: 40px; width: auto; object-fit: contain; vertical-align: middle; display: inline-block; } 807 808/* ---- preferred client picker ---- */ 809.client-row { display: flex; flex-wrap: wrap; gap: .5rem; } 810.client-opt { 811 display: inline-flex; 812 align-items: center; 813 gap: .45rem; 814 font: inherit; 815 font-size: .85rem; 816 padding: .45rem .7rem .45rem .5rem; 817 border: 1px solid var(--line); 818 border-radius: 999px; 819 background: var(--surface); 820 color: var(--ink); 821 cursor: pointer; 822 min-height: 44px; 823} 824.client-opt:hover { background: var(--hover); } 825.client-opt.sel { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); } 826.client-opt img { width: 22px; height: 22px; border-radius: 6px; object-fit: cover; } 827 828/* ---- icon-set marketplace ---- */ 829.iconset-list { display: flex; flex-direction: column; gap: .5rem; } 830.iconset-card { 831 display: flex; 832 align-items: center; 833 gap: .75rem; 834 width: 100%; 835 font: inherit; 836 text-align: left; 837 padding: .6rem .75rem; 838 border: 1px solid var(--line); 839 border-radius: 12px; 840 background: var(--surface); 841 color: var(--ink); 842 cursor: pointer; 843 min-height: 56px; 844} 845.iconset-card:hover { background: var(--hover); } 846.iconset-prev { display: inline-flex; align-items: center; gap: .35rem; min-width: 0; } 847.iconset-prev img { width: 26px; height: 26px; object-fit: contain; } 848.iconset-who { font-size: .85rem; color: var(--muted); margin-left: auto; word-break: break-all; } 849.iconset-try { font-size: .8rem; color: var(--accent); } 850 851/* the active try-on control — lives inline in the icon-sets section */ 852.tryon-active { 853 display: flex; 854 align-items: center; 855 justify-content: space-between; 856 gap: .75rem; 857 flex-wrap: wrap; 858 margin-bottom: .75rem; 859 padding: .75rem; 860 border: 1px solid var(--accent); 861 border-radius: 12px; 862 background: color-mix(in srgb, var(--accent) 8%, var(--surface)); 863 font-size: .9rem; 864} 865.tryon-actions { display: inline-flex; gap: .5rem; } 866 867.set-link { 868 display: inline-block; 869 margin-top: .75rem; 870 font: inherit; 871 font-size: .85rem; 872 border: none; 873 background: none; 874 color: var(--muted); 875 text-decoration: underline; 876 cursor: pointer; 877 padding: .4rem 0; 878} 879.set-link:hover { color: #e03131; } 880 881/* ---- per-drawing "show in explore" toggle (draw view) ---- */ 882.explore-toggle { 883 display: inline-flex; align-items: center; gap: .5rem; 884 align-self: center; min-height: 36px; 885 font-size: .85rem; color: var(--muted); cursor: pointer; 886} 887.explore-toggle input { width: 18px; height: 18px; accent-color: var(--accent); } 888 889/* ---- preference question controls (walkthrough + settings) ---- */ 890.pref-q { margin: 0 0 1.25rem; } 891.pref-q h4 { margin: 0 0 .25rem; font-size: .95rem; } 892.pref-q h4 a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; } 893.pref-q .hint { margin: 0 0 .5rem; } 894/* inline auto-save confirmation (no save button — changes persist on pick) */ 895.pref-status { font-size: .85rem; color: var(--muted); min-height: 1.2em; display: block; } 896.pref-status.ok { color: #2f9e44; } 897.pref-opts { display: flex; gap: .5rem; flex-wrap: wrap; } 898.pref-opt { 899 font: inherit; min-height: 44px; padding: .5rem .9rem; 900 border: 1px solid var(--line); border-radius: 10px; 901 background: var(--surface); color: var(--ink); cursor: pointer; 902} 903.pref-opt.sel { background: var(--accent); color: #fff; border-color: var(--accent); } 904.sheet-foot { margin-top: .75rem; } 905 906/* first-run walkthrough — give it a warm, branded moment, not a blank form */ 907.prefs-welcome { 908 display: flex; flex-direction: column; align-items: center; 909 text-align: center; gap: .6rem; padding: .25rem 0 1.25rem; 910} 911.prefs-mark { display: inline-flex; } 912.prefs-mark .slot-img { height: 48px; width: auto; } 913.prefs-welcome p { margin: 0; max-width: 34ch; color: var(--muted); font-size: .92rem; } 914.prefs-save { 915 width: 100%; justify-content: center; min-height: 48px; 916 font-weight: 600; font-size: 1rem; transition: background .2s, border-color .2s; 917} 918.prefs-save.ok { background: #2f9e44; border-color: #2f9e44; color: #fff; }