/* EarthOnline 3D: its own pages, drawn by src/views.js. Tokens and controls are public/v2/ui.css (Chat's); the frame
   and header public/style.css (Chat's). Black, white and grey; the models' pictures and the mark are the only colour.
   Pointing at a card changes its ground by one step and nothing else; nothing moves but the model you turn. */

/* the page: as wide as the header, 24px in (16px on a phone), so the search lines up with the brand above it */
.m3-main { padding: 0 24px 64px; min-height: 60vh; }
@media (max-width: 640px) { .m3-main { padding: 0 16px 48px; } }

/* ---- / : the search at the top left, then every model, more as you scroll --------------------------------------- */
.m3-home { padding-top: 24px; }

/* The search: EarthOnline Chat's lobby search, copied as it is (eol_chat/web/public/v2/home.css .home-find, .home-q,
   .home-find-go; Bonan 10-02: "所有 bubble 的 searchbar 都是这样才行"). A line, not a box: the words sit on an
   underline, the magnifier at its right end. 24px words on a 52px line, a 24px magnifier whose 2px stroke matches the
   letters. Clicking in changes nothing. Text longer than the line scrolls sideways inside it, and the part out of view
   fades out at that edge (app.js sets fade-start / fade-end). Here it stands at the top left, 640px at most. */
.home-find { display: flex; align-items: center; gap: 8px; margin: 0; border-bottom: 1px solid var(--line); }
.home-q {
  flex: 1; min-width: 0; height: 52px; margin: 0; padding: 0; border: 0; border-radius: 0; background: transparent;
  color: var(--fg); font: 400 var(--text-2xl)/var(--lh-2xl) var(--font); letter-spacing: var(--tracking-tight);
  outline: none; -webkit-appearance: none; appearance: none;
}
.home-q:focus-visible { outline: none; }
.home-q::-webkit-search-cancel-button, .home-q::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
.home-q.fade-start { -webkit-mask-image: linear-gradient(to right, transparent, #000 32px); mask-image: linear-gradient(to right, transparent, #000 32px); }
.home-q.fade-end { -webkit-mask-image: linear-gradient(to left, transparent, #000 32px); mask-image: linear-gradient(to left, transparent, #000 32px); }
.home-q.fade-start.fade-end { -webkit-mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 32px), transparent); }
/* the magnifier is a label: pointing at it changes its colour, nothing else; 2px lower, level with the letters' middle */
.home-find-go { flex: none; display: grid; place-items: center; width: 32px; height: 32px; margin-right: -4px; padding: 0; border: 0; background: none; color: var(--muted); cursor: pointer; }
.home-find-go:hover { color: var(--fg); }
.home-find-go { position: relative; top: 2px; }
.m3-home .home-find { max-width: 640px; }
/* nothing found, or nothing yet: said in the middle (Chat's) */
.home-none { margin: 48px 0 0; color: var(--muted); text-align: center; }

/* The grid: as many columns as fit, each at least 200px. A card is a picture, the name, and a small grey line. At rest
   only the picture has a ground; pointed at, the whole card takes one step of ground and the picture one more. The
   card's ground reaches 8px past the picture, so the grid is pulled out by those 8px and the pictures line up with
   the search above them. */
.m3-grid { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; margin: 24px -8px 0; padding: 0; }
.m3-card { min-width: 0; }
.m3-card-link { display: flex; flex-direction: column; min-width: 0; padding: 8px; border-radius: 16px; color: var(--fg); text-decoration: none; }
.m3-card-link:hover { background: var(--bg2); }
.m3-thumb { position: relative; display: grid; place-items: center; aspect-ratio: 1; overflow: hidden; border-radius: var(--radius-box); background: var(--bg2); }
.m3-card-link:hover .m3-thumb { background: var(--bg3); }
.m3-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
/* no picture, or one that did not load (app.js): a box, in grey */
.m3-ph { display: none; color: var(--muted); }
.m3-thumb.is-missing .m3-ph { display: grid; }
.m3-thumb.is-missing img { display: none; }
.m3-name { margin-top: 8px; font: 500 var(--text-sm)/var(--lh-sm) var(--font); }
.m3-meta { color: var(--muted); font-size: var(--text-sm); line-height: var(--lh-sm); white-space: nowrap; overflow: hidden; }
/* what the search found: a pale gold ground under dark letters (Chat's lobby) */
.m3-card mark { padding: 0 1px; border-radius: 3px; background: color-mix(in srgb, #FFC93C 55%, #fff); color: var(--on-fg); }
/* the next page is on its way: real cards, their ground grey and their words see-through, breathing (Chat's skeleton) */
.m3-card.is-skeleton { pointer-events: none; }
.m3-card.is-skeleton .m3-thumb { background: var(--bg3); }
.m3-card.is-skeleton :is(img, .m3-ph) { visibility: hidden; }
.m3-card.is-skeleton :is(.m3-name, .m3-meta) { width: fit-content; border-radius: 6px; background: var(--bg3); color: transparent; }
.m3-card.is-skeleton mark { background: none; color: transparent; }
@media (prefers-reduced-motion: no-preference) { .m3-card.is-skeleton { animation: m3-breathe 1.6s ease-in-out infinite; } }
@keyframes m3-breathe { 50% { opacity: .55; } }
.m3-more { height: 1px; }
@media (max-width: 640px) {
  .m3-home { padding-top: 16px; }
  .m3-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 16px; }
}

/* ---- /m/<id> : the model in 3D, and beside it what it is and how to use it ---------------------------------------- */
.m3-model { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 32px; align-items: start; padding-top: 24px; }
.m3-stage { position: relative; height: min(76vh, 760px); min-height: 360px; overflow: hidden; border-radius: var(--radius-box); background: var(--bg2); }
.m3-viewer { display: block; width: 100%; height: 100%; background: transparent; --poster-color: transparent; --progress-bar-color: rgb(255 255 255 / .5); --progress-bar-height: 2px; }
.m3-stage-still { width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; }
.m3-stage-still img { object-fit: contain; }
.m3-stage-note { position: absolute; inset: auto 16px 16px; margin: 0; color: var(--muted); font-size: var(--text-sm); line-height: var(--lh-sm); text-align: center; }
.m3-stage-note[hidden] { display: none; }

.m3-info { min-width: 0; }
.m3-title { margin: 0; font-size: var(--text-3xl); line-height: var(--lh-3xl); letter-spacing: var(--tracking-tight); overflow-wrap: anywhere; }
.m3-desc { margin: 8px 0 0; color: var(--muted); text-wrap: pretty; overflow-wrap: anywhere; }
.m3-actions { margin-top: 24px; }
.m3-actions .btn { display: flex; width: 100%; height: 40px; }
.m3-facts { margin: 24px 0 0; font-size: var(--text-sm); line-height: var(--lh-sm); }
.m3-facts > div { display: flex; justify-content: space-between; gap: 16px; padding: 6px 0; }
.m3-facts dt { flex: none; color: var(--muted); }
.m3-facts dd { min-width: 0; margin: 0; text-align: right; overflow-wrap: anywhere; }
.m3-facts a, .m3-files a { text-decoration: none; }
.m3-facts a:hover, .m3-files a:hover { color: var(--link); }
/* a detail page's small headings: words only, grey (taste) */
.m3-label { margin: 24px 0 8px; color: var(--muted); font: 500 var(--text-sm)/var(--lh-sm) var(--font); }
.m3-credit-text { margin: 0 0 12px; padding: 12px 14px; border-radius: var(--radius); background: var(--bg2); font-size: var(--text-sm); line-height: var(--lh-sm); overflow-wrap: anywhere; }
.m3-files-note { margin: 0 0 8px; color: var(--muted); font-size: var(--text-sm); line-height: var(--lh-sm); }
.m3-files ul { list-style: none; margin: 0; padding: 0; font-size: var(--text-sm); line-height: var(--lh-sm); }
.m3-files li { display: flex; justify-content: space-between; gap: 16px; padding: 4px 0; }
.m3-files li a { min-width: 0; overflow-wrap: anywhere; }
.m3-files li span { flex: none; color: var(--muted); }
@media (max-width: 900px) {
  .m3-model { grid-template-columns: minmax(0, 1fr); gap: 24px; padding-top: 16px; }
  .m3-stage { height: auto; min-height: 0; aspect-ratio: 1; }
}

/* the foot of a model page: Report, or Delete for the one who uploaded it; after a report, a line that says it went */
.m3-foot { margin-top: 24px; }
.m3-foot .btn-ghost { margin-left: -12px; }
.m3-foot-note { margin: 0; color: var(--muted); font-size: var(--text-sm); line-height: var(--lh-sm); }
.dialog-form .label em { font-style: normal; font-weight: 400; color: var(--muted); }

/* ---- /me : My models, and the two ways on (Account settings is Chat's; Upload) ---------------------------------- */
.m3-me { padding-top: 24px; }
.m3-me-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; }
.m3-page-title { margin: 0; font-size: var(--text-3xl); line-height: var(--lh-3xl); letter-spacing: var(--tracking-tight); }
/* a count after a heading: as large as the heading, grey and regular (taste) */
.m3-count { color: var(--muted); font-weight: 400; }
.m3-me-acts { display: flex; gap: 8px; }

/* ---- /upload : the model as it will look, beside what to say about it --------------------------------------------- */
.m3-upload-form { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 32px; align-items: start; padding-top: 24px; }
.m3-upload-stage { display: grid; place-items: center; }
.m3-upload-stage > .m3-viewer { position: absolute; inset: 0; }
.m3-pick { display: grid; justify-items: center; gap: 12px; max-width: 320px; padding: 24px; text-align: center; cursor: pointer; }
.m3-pick-note { color: var(--muted); font-size: var(--text-sm); line-height: var(--lh-sm); }
.m3-pick.is-picked { position: absolute; top: 12px; right: 12px; z-index: 1; display: block; max-width: none; padding: 0; }
.m3-pick.is-picked .m3-pick-note { display: none; }
.m3-pick.is-picked .btn { height: 32px; padding: 0 12px; }
.m3-pick:focus-within .btn { box-shadow: 0 0 0 3px var(--ring-soft); }
.m3-fields { display: grid; gap: 16px; margin-top: 24px; }
.m3-fields .field > .label em, .m3-licenses legend em { font-style: normal; font-weight: 400; color: var(--muted); }
.m3-licenses { margin: 0; padding: 0; border: 0; min-width: 0; }
.m3-licenses legend { padding: 0; margin-bottom: 8px; }
/* the license: two choices, each a row with its one-line meaning; nothing picked until the uploader picks */
.m3-license { display: flex; gap: 10px; align-items: flex-start; padding: 8px 0; cursor: pointer; }
.m3-license input { margin: 3px 0 0; accent-color: var(--fg); }
.m3-license > span { display: grid; font-size: var(--text-sm); line-height: var(--lh-sm); }
.m3-license > span > span { color: var(--muted); }
.m3-upload-error { margin: 16px 0 0; color: var(--fg); font-size: var(--text-sm); line-height: var(--lh-sm); }
.m3-upload-error[hidden] { display: none; }
.m3-upload .field-note { margin-top: 12px; }
@media (max-width: 900px) {
  .m3-upload-form { grid-template-columns: minmax(0, 1fr); gap: 24px; padding-top: 16px; }
}

/* ---- a page with one message (not found, an error) ---- */
.m3-message { max-width: 560px; margin: 96px auto 0; text-align: center; }
.m3-message h1 { margin: 0 0 12px; font-size: var(--text-4xl); line-height: var(--lh-4xl); letter-spacing: var(--tracking-tight); }
.m3-message p { margin: 0 0 24px; color: var(--muted); }
