/* Single-page publish flow. Depends on theme.css tokens, base.css reset, and the primitives layer (.blueprint-panel, .button, .tab, .status-pill, .field-label, .card-meta, .blueprint-media). Page layer — loads after the shell. */ .publish-page { flex: 1; min-height: 0; width: 100%; max-width: 56rem; margin: 0 auto; padding: clamp(0.75rem, 2vw, 1.75rem) clamp(1rem, 3vw, 2.5rem); display: flex; flex-direction: column; gap: 0.9rem; } /* Signed-out callout reuses the panel + session-control vocabulary. */ .publish-intro, .publish-signed-out { display: flex; flex-direction: column; gap: 0.75rem; padding: clamp(1.25rem, 3vw, 2rem); } .publish-intro h1, .publish-signed-out h1, .publish-signed-out h2 { margin: 0; color: var(--color-emphasis); letter-spacing: -0.03em; } /* Header: title + draft/published status + autosave state + save affordance. */ .publish-head { display: flex; flex-direction: column; gap: 0.35rem; } .publish-head-row { display: flex; align-items: center; flex-wrap: wrap; gap: 0.6rem; } .publish-head-row h1 { margin: 0; color: var(--color-emphasis); letter-spacing: -0.03em; } .publish-save { margin-left: auto; font-size: 0.85rem; } .publish-save-state { margin: 0; color: var(--color-muted); font-family: var(--font-mono); font-size: 0.74rem; } /* Hero upload zone — the primary element of the signed-in page. */ .publish-hero { display: flex; flex-direction: column; gap: 0.75rem; padding: clamp(1rem, 2.5vw, 1.75rem); } .publish-dropzone { position: relative; display: block; cursor: pointer; border: 1px dashed var(--color-border); border-radius: var(--radius-panel); background: color-mix(in srgb, var(--color-overlay) 30%, transparent); padding: clamp(1.5rem, 4vw, 2.5rem); transition: border-color 150ms ease-out, background 150ms ease-out; } .publish-dropzone:hover, .publish-dropzone:focus-within { border-color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 6%, transparent); } .publish-dropzone.is-drag-over { border-color: var(--color-action); border-style: solid; background: color-mix(in srgb, var(--color-action) 10%, transparent); } .publish-dropzone-body { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; text-align: center; pointer-events: none; } .publish-dropzone-title { margin: 0; color: var(--color-emphasis); font-weight: 600; } .publish-dropzone-hint { margin: 0; } /* (Drag-and-drop target is the dropzone label itself; the body overlay stays pointer-transparent so drops and label-clicks reach the input.) */ /* Body panel + section copy. */ .wizard-body { display: flex; flex-direction: column; gap: 1rem; padding: clamp(1rem, 2.5vw, 1.75rem); } .wizard-body h2 { margin: 0; color: var(--color-emphasis); letter-spacing: -0.02em; } .wizard-subhead { margin: 0; color: var(--color-emphasis); font-size: 1rem; } /* Form fields — mirror the shell input vocabulary, sharp corners. */ .field { display: flex; flex-direction: column; gap: 0.35rem; } .field-input { width: 100%; min-height: 2.1rem; padding: 0.5rem 0.65rem; border: 1px solid var(--color-border); border-radius: var(--radius-panel); background: var(--color-surface); color: var(--color-text); font-family: var(--font-ui); font-size: 0.95rem; } .field-input::placeholder { color: var(--color-subtle); } .field-input:focus, .field-input:focus-visible { outline: 2px solid color-mix(in srgb, var(--color-primary) 25%, transparent); outline-offset: 1px; border-color: var(--color-primary); } .field-textarea { min-height: 4.5rem; resize: vertical; line-height: 1.5; } .field-textarea-tall { min-height: 8rem; } .field-help { color: var(--color-muted); } .publish-license-field { display: flex; flex-direction: row; align-items: center; flex-wrap: wrap; gap: 0.5rem 0.75rem; } .publish-license-field .field-label { flex: none; } .publish-license-controls { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; flex: 1; min-width: min(100%, 31rem); } .publish-license-select { flex: 0 0 12rem; width: 12rem; min-width: 12rem; } .publish-license-custom { flex: 1 1 16rem; min-width: 14rem; max-width: 22rem; } /* Inline name field — prominent, the first edit after a drop. */ .publish-name-field { max-width: 32rem; } /* Files list — also a drop target for adding more parts. */ .publish-files { display: flex; flex-direction: column; gap: 0.6rem; border: 1px dashed transparent; border-radius: var(--radius-panel); padding: 0.5rem; transition: border-color 150ms ease-out, background 150ms ease-out; } .publish-files.is-drag-over { border-color: var(--color-action); background: color-mix(in srgb, var(--color-action) 8%, transparent); } /* Models & parts. */ .wizard-model { display: flex; flex-direction: column; gap: 0.75rem; padding: 1rem; border: 1px solid var(--color-border); border-radius: var(--radius-panel); background: color-mix(in srgb, var(--color-overlay) 40%, transparent); } .wizard-model-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; } .wizard-model-name { flex: 1; min-width: 12rem; } .wizard-part-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; } .wizard-part { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; } .wizard-part-advanced { flex-direction: column; align-items: stretch; gap: 0.75rem; padding: 0.75rem; border: 1px solid var(--color-border); border-radius: var(--radius-panel); } .wizard-part-main { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; } .wizard-part-name { flex: 1; min-width: 10rem; } .wizard-part-meta { white-space: nowrap; } .wizard-part-meta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 0.6rem; } .publish-field-wide { grid-column: 1 / -1; } .wizard-empty { margin: 0; color: var(--color-muted); font-style: italic; } /* File input wrapped by a styled label button; hide the raw control. */ .wizard-file-button { cursor: pointer; } .wizard-file-input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; } /* Upload progress + status. */ .wizard-upload-status { display: flex; align-items: center; gap: 0.6rem; color: var(--color-subtle); font-size: 0.9rem; } .wizard-progress-bar { position: relative; flex: none; width: 8rem; height: 0.4rem; border-radius: var(--radius-pill); overflow: hidden; background: var(--color-overlay); } .wizard-progress-bar::after { content: ""; position: absolute; inset: 0; width: 40%; border-radius: inherit; background: var(--color-primary); animation: wizard-progress 1.1s ease-in-out infinite; } @keyframes wizard-progress { from { transform: translateX(-110%); } to { transform: translateX(310%); } } /* Images. */ .wizard-image-group { display: flex; flex-direction: column; gap: 0.6rem; } .wizard-image-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; } .wizard-image { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; } .wizard-image-thumb { flex: none; width: 5rem; aspect-ratio: 4 / 3; border: 1px solid var(--color-border); border-radius: var(--radius-panel); overflow: hidden; } .wizard-image-img { display: block; width: 100%; height: 100%; object-fit: cover; } .wizard-image-alt { flex: 1; min-width: 12rem; } /* Progressive disclosure sections. */ .publish-sections { display: flex; flex-direction: column; gap: 0.5rem; } .publish-disclosure { border: 1px solid var(--color-border); border-radius: var(--radius-panel); background: var(--color-surface); } .publish-disclosure-summary { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; padding: 0.6rem 0.75rem; cursor: pointer; list-style: none; } .publish-disclosure-summary::-webkit-details-marker { display: none; } .publish-disclosure-title { margin: 0; color: var(--color-emphasis); font-size: 0.95rem; font-weight: 600; } .publish-disclosure-hint { margin: 0; } .publish-disclosure-body { padding: 0.75rem; border-top: 1px solid var(--color-border); display: flex; flex-direction: column; gap: 0.75rem; } /* Dimensions (bbox) inputs. */ .publish-bbox { border: 0; padding: 0; margin: 0; } .publish-bbox-row { display: flex; gap: 0.5rem; flex-wrap: wrap; } .publish-bbox-row .field { flex: 1; min-width: 4.5rem; } /* "Works with" compatibility chips. */ .publish-compat-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.4rem; } .publish-compat-chip { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.25rem 0.5rem; border: 1px solid var(--color-border); border-radius: var(--radius-pill); background: color-mix(in srgb, var(--color-overlay) 40%, transparent); font-size: 0.85rem; } .publish-compat-remove { padding: 0 0.35rem; line-height: 1; border: 0; background: none; color: var(--color-muted); } .publish-compat-remove:hover { color: var(--color-error); } /* Review/confirm. */ .wizard-review { display: flex; flex-direction: column; gap: 0.6rem; } .wizard-review-row { display: grid; grid-template-columns: 9rem 1fr; gap: 0.75rem; align-items: start; padding-bottom: 0.6rem; border-bottom: 1px solid var(--color-border); } .wizard-review-row.is-error { color: var(--color-error); } .wizard-review-row.is-error .field-label { color: var(--color-error); } .wizard-review-models { display: flex; flex-direction: column; gap: 0.4rem; } .wizard-review-model { display: flex; align-items: baseline; gap: 0.6rem; } /* Validation summary. */ .wizard-issues { gap: 0.5rem; } /* Publish action row — the single primary action, clearly distinct. */ .wizard-publish-row { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; margin-top: 0.5rem; } .wizard-publish { font-size: 0.95rem; } /* Resume list. */ .wizard-resume { display: flex; flex-direction: column; gap: 0.6rem; padding: 1rem clamp(1rem, 2.5vw, 1.5rem); } .wizard-resume-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; } .wizard-resume-item { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; padding: 0.6rem 0.75rem; border: 1px solid var(--color-border); border-radius: var(--radius-panel); } .wizard-resume-meta { display: flex; flex-direction: column; gap: 0.15rem; } .wizard-resume-name { font-weight: 600; color: var(--color-text); } /* Errors. */ .wizard-error { margin: 0; color: var(--color-error); font-size: 0.9rem; } /* Published success. */ .wizard-published { gap: 0.75rem; } .wizard-published h2 { margin: 0; color: var(--color-emphasis); } @media (max-width: 32rem) { .wizard-review-row { grid-template-columns: 1fr; gap: 0.25rem; } } @media (prefers-reduced-motion: reduce) { .wizard-progress-bar::after { animation: none; width: 100%; opacity: 0.6; } .publish-dropzone { transition: none; } }