/* =========================================== PAYMENTS TAB (replaces inline styles in user_payments.html) =========================================== */ /* Canonical "stack row", title-on-left + actions-on-right header bar. One primitive; per-context modifiers handle gap, wrap, alignment, margins. Aliases below cover existing per-tab class names (kept as JS hooks). */ .stack-row, .content-header, .user-media-header, .transactions-header, .analytics-range-bar, .cart-multi-bar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--gap-section); } .stack-row--tight { gap: var(--gap-section); flex-wrap: nowrap; } .stack-row--top { align-items: flex-start; } .stack-row--bordered, .transactions-header { margin-bottom: var(--gap-section); padding-bottom: var(--gap-section); border-bottom: 1px solid var(--border); } .content-header, .user-media-header, .analytics-range-bar { margin-bottom: var(--gap-section); } .cart-multi-bar { margin-bottom: var(--gap-pane); padding: var(--gap-section); background: var(--surface-sunken); border: 1px solid var(--border); } /* Canonical list row (flex, gap, padding, bottom border). Aliases below cover the per-tab variants. They exist as JS hooks but share the same look. */ .list-row, .psection-row, .section-mgmt-row, .bundle-picker-row, .checklist-row { display: flex; align-items: center; gap: var(--gap-section); padding: var(--gap-group) 0; border-bottom: 1px solid var(--border); } .list-row:last-child, .psection-row:last-child, .section-mgmt-row:last-child, .bundle-picker-row:last-child, .checklist-row:last-child { border-bottom: none; } .warn-glyph { font-size: var(--text-subhead); color: var(--warning); } .card-h { margin: 0 0 var(--gap-section) 0; font-size: var(--text-body); } .amount-big { font-size: var(--text-subhead); font-weight: bold; } .account-details { margin-top: var(--gap-section); padding-top: var(--gap-section); border-top: 1px solid var(--border); } .account-details summary { cursor: pointer; } .account-details-id { font-size: var(--text-fine); opacity: 0.5; font-family: var(--font-mono); margin-top: var(--gap-bound); } .stripe-actions { display: flex; gap: var(--gap-section); flex-wrap: wrap; } .stripe-actions-disconnect { margin-left: auto; } .fee-breakdown { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-peer); font-size: var(--text-note); } .fee-row { display: flex; justify-content: space-between; padding: var(--gap-peer) 0; border-bottom: 1px solid var(--border); } .checkbox-row { display: flex; align-items: flex-start; gap: var(--gap-peer); cursor: pointer; font-size: var(--text-note); } .check-inline { width: auto; margin-top: var(--gap-bound); } .stripe-connect-prompt { text-align: center; padding: var(--gap-pane); } .stripe-logo { opacity: 0.8; } .stripe-connect-btn { background: var(--stripe); padding: var(--gap-section) var(--gap-page); } .export-row { display: flex; justify-content: flex-end; margin-bottom: var(--gap-section); } .splits-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-section); margin-bottom: var(--gap-section); } .tip-message { max-width: 300px; overflow: hidden; text-overflow: ellipsis; } .transactions-title { font-size: var(--text-subhead); } /* =========================================== CREATOR TAB (replaces inline styles in user_creator.html) =========================================== */ .creator-tab-section { padding: var(--gap-page); } .creator-tab-section--centered { text-align: center; } .creator-tab-section--no-top { padding-top: 0; } .creator-h2 { font-size: var(--text-subhead); margin-bottom: var(--gap-section); } .creator-h2--sm { font-size: var(--text-subhead); } .creator-section-label { margin-left: var(--gap-page); margin-right: var(--gap-page); } .creator-form-section { padding: 0 var(--gap-page); } .creator-plan-box { background: var(--surface-overlay); padding: var(--gap-section) var(--gap-pane); } .creator-plan-head { display: flex; align-items: center; gap: var(--gap-section); margin-bottom: var(--gap-peer); flex-wrap: wrap; } .creator-plan-name { font-family: var(--font-display); font-weight: bold; font-size: var(--text-lead); } /* Founder pricing, two states, and neither is a status tone: locked-for-life is emphasis and pending-lock-in is an aside. They were a --content fill and a --surface-sunken fill back when every badge was filled; as coloured text the same distinction is full-strength ink against muted. */ .badge--founder-locked { color: var(--content); font-weight: bold; } .badge--founder-pending { color: var(--content-muted); } .founder-callout { background: var(--surface-overlay); border-left: 3px solid var(--content); padding: var(--gap-section); } .creator-tier-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--gap-section); } .creator-tier-card { background: var(--surface-overlay); padding: var(--gap-section); text-align: center; } .creator-tier-name { font-family: var(--font-display); font-weight: bold; font-size: var(--text-body); margin-bottom: var(--gap-bound); } .creator-tier-link { color: inherit; text-decoration: none; border-bottom: 1px solid var(--border); } .creator-tier-sub { font-size: var(--text-fine); opacity: 0.7; } .creator-tier-storage { font-size: var(--text-fine); } .creator-tier-buttons { display: flex; flex-direction: column; gap: var(--gap-peer); } .creator-tier-btn { font-size: var(--text-note); width: 100%; } .strike-dim { opacity: 0.5; text-decoration: line-through; } .storage-box { background: var(--surface-overlay); padding: var(--gap-section) var(--gap-pane); } .storage-row { display: flex; justify-content: space-between; margin-bottom: var(--gap-peer); font-size: var(--text-note); } .storage-breakdown { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-bound) var(--gap-pane); margin-top: var(--gap-section); font-size: var(--text-note); } .broadcast-head { display: flex; justify-content: space-between; align-items: flex-start; } .broadcast-desc { flex: 1; } .broadcast-export { margin-left: var(--gap-section); } .creator-divider { margin: 0 var(--gap-page); border-color: var(--border); } .creator-intro { line-height: 1.6; } .creator-pitch-box { background: var(--surface-overlay); padding: var(--gap-pane); } .mono-sm { font-family: var(--font-mono); font-size: var(--text-note); } /* =========================================== PROJECT CONTENT TAB (replaces inline styles in project_content.html) =========================================== */ .empty-state--lg { padding: var(--gap-page) var(--gap-section); } .content-filters { display: flex; gap: var(--gap-section); margin-bottom: var(--gap-section); align-items: center; flex-wrap: wrap; } .content-filter-search { flex: 1; min-width: 180px; padding: var(--gap-peer) var(--gap-group); font-size: var(--text-note); } .content-filter-select { padding: var(--gap-peer); font-size: var(--text-note); } .bulk-action-bar { padding: var(--gap-section); margin-bottom: var(--gap-section); background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-square); display: flex; align-items: center; gap: var(--gap-peer); flex-wrap: wrap; opacity: 0.4; } .bulk-action-bar--active { opacity: 1; } .bulk-count { font-weight: bold; min-width: 5rem; } .bulk-deselect { margin-left: auto; } .danger-text { color: var(--danger); } .bulk-form { margin-bottom: var(--gap-section); padding: var(--gap-section); background: var(--surface-sunken); border: 1px solid var(--border); border-radius: var(--radius-square); } .bulk-form-row { display: flex; gap: var(--gap-section); align-items: end; } .bulk-form-label { font-size: var(--text-note); display: block; margin-bottom: var(--gap-bound); } /* Sortable table column header The cursor and the caret are NOT here. `.table-heading[data-sortable]` and `.table-heading[aria-sort="..."]::after` are generated into static/layout.css by makeover-webview out of `Column::sortable` and `Column::sorted`. This file carried two hand-written copies of the same fact -- `.sortable-th` here and `.data-table th.sortable` up at the data-table block -- and a third channel in tab-project-content.js, which wrote the glyph as text and toggled `.sort-arrow--active`. Three vocabularies, one state, and the generated pair matched nothing because no heading carried `.table-heading`. The focus ring stays: it is this app's focus treatment, not a restatement of the caret, and makeover emits no focus rule for a heading. */ .table-heading[data-sortable] { user-select: none; transition: background 0.2s ease; } .table-heading[data-sortable]:hover { background: var(--border); } .table-heading[data-sortable]:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; } /* Data-table column-width utilities (numeric width hints, kept as classes to avoid inline `style="width: NN%"`) */ .col-3 { width: 3%; } .col-5 { width: 5%; } .col-8 { width: 8%; } .col-10 { width: 10%; } .col-12 { width: 12%; } .col-15 { width: 15%; } .col-20 { width: 20%; } .col-32 { width: 32%; } .col-45 { width: 45%; } /* Pixel-width utilities for inputs and narrow fixed-width controls. Use on form inputs that can't be sized by their parent column. */ .w-80 { width: 80px; } .w-100 { width: 100px; } .w-120 { width: 120px; } .w-180 { width: 180px; } .w-220 { width: 220px; } .w-260 { width: 260px; } .w-full { width: 100%; } .maxw-320 { max-width: 320px; } /* Canonical input shape modifiers. One base form-input look (defined globally at line ~365 input[type], textarea, select) plus these size + feature variants. Apply alongside the per-tab class which acts as a JS hook. */ .input--xs { padding: var(--gap-bound) var(--gap-peer); font-size: var(--text-note); } .input--sm { padding: var(--gap-bound) var(--gap-peer); font-size: var(--text-note); } .input--mono { font-family: var(--font-mono); } .input--upper { text-transform: uppercase; } .input--numeric { text-align: right; } .order-arrow-btn { padding: var(--gap-bound); font-size: var(--text-fine); line-height: 1; } .bundle-toggle { background: none; border: none; cursor: pointer; padding: 0 var(--gap-bound) 0 0; font-size: var(--text-fine); color: var(--content-muted); } .bundle-child-cell { padding-left: var(--gap-page); } .bundle-child-title { opacity: 0.85; } .bundle-child-arrow { color: var(--content-muted); margin-right: var(--gap-bound); } .item-actions { display: flex; gap: var(--gap-peer); } .badge--inline-tiny { font-size: var(--text-fine); margin-left: var(--gap-bound); opacity: 0.7; } .deleted-items-details { margin-top: var(--gap-page); } .deleted-items-summary { cursor: pointer; font-size: var(--text-body); opacity: 0.7; } .section-divider { margin: var(--gap-page) 0; border: none; border-top: 1px solid var(--border); } .inline-rename-input { font-weight: bold; width: 100%; padding: var(--gap-bound) var(--gap-peer); font-size: inherit; } /* =========================================== ITEM DETAILS TAB (replaces inline styles in item_details.html) =========================================== */ /* Compact button utility (small icon-side actions) */ .btn-compact { padding: var(--gap-peer) var(--gap-section); } .ml-2 { margin-left: var(--gap-peer); } .cursor-pointer { cursor: pointer; } .inline { display: inline; } .tag-search-wrap { position: relative; } .tag-suggestions { position: absolute; z-index: var(--z-dropdown); background: var(--surface-sunken); border: 1px solid var(--border); width: 100%; max-height: 200px; overflow-y: auto; } .advanced-details { margin-top: var(--gap-pane); } .advanced-summary { cursor: pointer; font-size: var(--text-body); opacity: 0.8; } /* Bundle table inside item-details */ .bundle-table { width: 100%; border-collapse: collapse; } .bundle-table-head { text-align: left; font-size: var(--text-fine); opacity: 0.7; text-transform: uppercase; letter-spacing: 0.03em; } .bundle-row { border-bottom: 1px solid var(--border); } .bundle-cell { padding: var(--gap-peer); } .bundle-cell--first { padding-left: 0; } .bundle-cell--actions { width: 60px; } .bundle-cell--desc { font-size: var(--text-note); opacity: 0.8; } .bundle-cell--file { font-size: var(--text-note); } .bundle-remove-btn { padding: var(--gap-bound) var(--gap-peer); font-size: var(--text-fine); } .bundle-add-row { margin-top: var(--gap-section); display: flex; gap: var(--gap-section); align-items: center; } .bundle-existing-details { margin-top: var(--gap-section); } .bundle-existing-summary { cursor: pointer; font-size: var(--text-note); opacity: 0.7; } .bundle-existing-row { margin-top: var(--gap-peer); display: flex; gap: var(--gap-peer); align-items: center; } .bundle-existing-select { flex: 1; padding: var(--gap-peer); } .sections-intro { font-size: var(--text-note); opacity: 0.7; margin: var(--gap-section) 0 var(--gap-section); } .section-mgmt-title { flex: 1; font-weight: bold; } .section-edit-btn, .section-del-btn { padding: var(--gap-bound) var(--gap-group); font-size: var(--text-fine); } .section-add-details { margin-top: var(--gap-section); } .section-add-summary { cursor: pointer; font-size: var(--text-body); } .section-edit-modal { margin-top: var(--gap-section); padding: var(--gap-section); background: var(--surface-sunken); } .section-edit-actions { display: flex; gap: var(--gap-peer); } .publish-note { margin: var(--gap-section) 0; opacity: 0.7; text-align: left; } /* =========================================== CONTENT WIZARD STEP (replaces inline styles in wizards/steps/item/content.html) =========================================== */ /* (Wizard upload-status + slim progress moved into canonical .upload-status* / .progress-bar-container--slim primitives near top of file.) */ /* Bundle items picker, server-rendered rows and JS-appended rows share these. */ .bundle-picker-row-title { flex: 1; } .bundle-picker-row-type { font-size: var(--text-fine); opacity: 0.6; } .bundle-picker-row-unlisted { font-size: var(--text-fine); display: flex; align-items: center; gap: var(--gap-bound); } /* Batch upload queue table. */ .batch-queue-table { width: 100%; border-collapse: collapse; } .batch-queue-table thead tr { border-bottom: 2px solid var(--border); text-align: left; } .batch-queue-table th, .batch-queue-table td { padding: var(--gap-peer); font-size: var(--text-note); } .batch-queue-table th:first-child, .batch-queue-table td:first-child { padding-left: 0; } .batch-queue-table th:last-child, .batch-queue-table td:last-child { padding-right: 0; text-align: right; } .batch-queue-table tbody tr { border-bottom: 1px solid var(--border); } .batch-queue-name { max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* =========================================== ACCOUNT TAB (replaces inline styles in partials/tabs/user_account.html) =========================================== */ /* Canonical solid-tint callout (one of these in the codebase). Distinct from .alert (left-border) and .banner (full-bleed page notice). Variants: - .callout--danger (light bg, danger border, moderation, errors) - .callout--warning (light bg, warning border, DNS, email-not-verified) - .callout--solid-warning (full saturation warning bg, dark text, partial checkout) */ .callout { padding: var(--gap-section); margin-bottom: var(--gap-section); font-size: var(--text-note); border: 1px solid; } .callout--danger { background: color-mix(in oklch, var(--danger) 10%, var(--surface-page)); border-color: var(--danger); } .callout--warning { background: color-mix(in oklch, var(--warning) 14%, var(--surface-page)); border-color: var(--warning); } .callout--solid-warning { background: var(--warning); color: var(--primary-dark); border-color: transparent; padding: var(--gap-section); } .callout-title { text-transform: capitalize; } .callout-meta { opacity: 0.6; margin-left: var(--gap-peer); } .callout-body { margin: var(--gap-peer) 0 0 0; } .callout-hint { font-size: var(--text-note); margin-top: var(--gap-peer); } .account-mod-history { margin-top: var(--gap-section); } .account-mod-history summary { cursor: pointer; font-size: var(--text-note); opacity: 0.7; } .account-mod-history-list { margin-top: var(--gap-peer); } .account-mod-history-item { padding: var(--gap-peer) 0; border-bottom: 1px solid var(--border); font-size: var(--text-note); } .account-mod-history-reason { margin: var(--gap-bound) 0 0 0; opacity: 0.8; } .account-tip-card-title { font-weight: bold; margin-bottom: var(--gap-peer); } .account-tip-list { display: flex; flex-direction: column; gap: var(--gap-bound); opacity: 0.8; } /* Resend-verification button needs left spacing from preceding strong. */ .account-resend-btn { margin-left: var(--gap-peer); } /* Cluster of small inline forms (manage-billing / cancel / resume). */ .inline-form { display: inline; } /* Notification preferences, bare fieldset + monospace legend. */ .pref-fieldset { border: none; padding: 0; margin: 0 0 var(--gap-section) 0; } .pref-fieldset--last { margin-bottom: var(--gap-peer); } .pref-legend { font-family: var(--font-mono); font-size: var(--text-note); font-weight: bold; margin-bottom: var(--gap-peer); } /* The cannot-opt-out list, rendered from email::OperationalKind. Reads as reference material rather than as more settings: no controls, and the justification sits under its label rather than beside it. */ .operational-mail { margin: var(--gap-peer) 0 0 0; } .operational-mail dt { font-weight: bold; font-size: var(--text-note); margin-top: var(--gap-peer); } .operational-mail dd { margin: 0; opacity: 0.8; font-size: var(--text-note); } /* =========================================== PROJECT CODE TAB (replaces inline styles in partials/tabs/project_code.html) =========================================== */ .proj-code-docs-link { margin-left: var(--gap-section); } .proj-code-linked-list { margin-bottom: var(--gap-pane); } .proj-code-linked-list > label { margin-bottom: var(--gap-peer); display: block; } .proj-code-repo { margin-bottom: var(--gap-section); padding: var(--gap-section); background: var(--surface-overlay); } .proj-code-repo-row { display: flex; align-items: center; gap: var(--gap-section); } .proj-code-repo-link { flex: 1; } .proj-code-repo .danger { padding: var(--gap-bound) var(--gap-section); font-size: var(--text-note); } .proj-code-collab-block { margin-top: var(--gap-peer); padding-top: var(--gap-peer); border-top: 1px solid var(--border); } .proj-code-collab-label { font-size: var(--text-note); margin-bottom: var(--gap-bound); display: block; } .proj-code-collab-row { display: flex; align-items: center; gap: var(--gap-peer); margin-bottom: var(--gap-bound); font-size: var(--text-note); } .proj-code-collab-name { flex: 1; } .proj-code-collab-readonly { opacity: 0.5; } .proj-code-add-collab-row { display: flex; gap: var(--gap-peer); align-items: center; } .proj-code-add-collab-row .collab-username-input { flex: 1; font-size: var(--text-note); padding: var(--gap-bound) var(--gap-peer); } .proj-code-add-collab-row .collab-add-btn { white-space: nowrap; } .proj-code-link-row { display: flex; gap: var(--gap-peer); align-items: center; } .proj-code-link-row #link-repo-select { flex: 1; } .proj-code-link-row #link-repo-btn { white-space: nowrap; } .proj-code-create-section { margin-top: var(--gap-pane); padding-top: var(--gap-section); border-top: 1px solid var(--border); } .proj-code-create-section #create-repo-name { flex: 1; } .proj-code-create-section #create-repo-btn { white-space: nowrap; } .proj-code-create-status { margin-top: var(--gap-bound); } .proj-code-create-status.is-error { color: var(--danger); } .proj-code-disabled { padding: var(--gap-page); text-align: center; opacity: 0.7; } /* =========================================== ADMIN REPORT ENTRIES (replaces inline styles in partials/admin_report_entries.html) =========================================== */ .admin-report-table { width: 100%; border-collapse: collapse; font-size: var(--text-note); } .admin-report-table thead tr { border-bottom: 2px solid var(--border); text-align: left; } .admin-report-table tbody tr { border-bottom: 1px solid var(--border); } .admin-report-table th, .admin-report-table td { padding: var(--gap-peer); } .admin-report-table td.admin-report-reason { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .admin-report-table td.admin-report-date { white-space: nowrap; } .admin-report-target-type { opacity: 0.5; font-size: var(--text-fine); } .admin-report-status-open { color: var(--action); font-weight: 600; } .admin-report-status-closed { opacity: 0.6; } .admin-report-resolve-form { display: inline-flex; gap: var(--gap-bound); align-items: center; } .admin-report-resolve-form input[type="text"] { width: 120px; padding: var(--gap-bound) var(--gap-peer); font-size: var(--text-fine); } .admin-report-dismiss-form { display: inline; } .admin-report-admin-notes { font-size: var(--text-fine); opacity: 0.6; } /* =========================================== PROJECT PROMOTIONS TAB (replaces inline styles in partials/tabs/project_promotions.html) =========================================== */ .proj-promo-form { margin-bottom: var(--gap-page); } .proj-promo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-section) var(--gap-pane); max-width: 500px; } .proj-promo-grid--bordered { margin-top: var(--gap-section); padding-top: var(--gap-section); border-top: 1px solid var(--border); } .proj-promo-trial-fields { display: none; max-width: 500px; margin-top: var(--gap-section); } .proj-promo-trial-fields.is-visible { display: block; } .proj-promo-grid.is-hidden, .proj-promo-trial-fields.is-hidden { display: none; } .proj-promo-form .form-group { margin-bottom: 0; } .proj-promo-form .form-group label { font-size: var(--text-note); } .proj-promo-trial-group { max-width: 240px; } .proj-promo-scope { grid-column: 1 / -1; } .proj-promo-actions { margin-top: var(--gap-section); } .proj-promo-hint { margin-top: var(--gap-peer); } /* =========================================== PROJECT SYNCKIT TAB (replaces inline styles in partials/tabs/project_synckit.html) =========================================== */ .proj-synckit-intro { margin-bottom: var(--gap-section); } .proj-synckit-intro-secondary { margin-bottom: var(--gap-pane); } .proj-synckit-create { margin-bottom: var(--gap-pane); } .proj-synckit-create-body { padding: var(--gap-section); background: var(--surface-overlay); border: 1px solid var(--border); } .proj-synckit-create-form { display: flex; flex-direction: row; gap: var(--gap-section); align-items: flex-end; } .proj-synckit-label { display: block; font-size: var(--text-note); margin-bottom: var(--gap-bound); } .proj-synckit-code { font-size: var(--text-fine); } .proj-synckit-code--wrap { font-size: var(--text-fine); word-break: break-all; } .proj-synckit-code--selectable { font-size: var(--text-note); word-break: break-all; user-select: all; } .proj-synckit-btn-tight { margin-left: var(--gap-peer); padding: var(--gap-bound) var(--gap-peer); font-size: var(--text-fine); } .proj-synckit-btn-row { padding: var(--gap-bound) var(--gap-peer); font-size: var(--text-fine); } .proj-synckit-btn-row + .proj-synckit-btn-row { margin-left: var(--gap-bound); } .proj-synckit-hint-inline { font-size: var(--text-fine); margin-left: var(--gap-bound); } .proj-synckit-hint-warn { font-size: var(--text-fine); color: var(--danger); } .proj-synckit-status-active { color: var(--success); } .proj-synckit-status-inactive { color: var(--danger); } .proj-synckit-new-key { padding: var(--gap-section); background: var(--surface-overlay); border: 1px solid var(--border); margin-top: var(--gap-peer); } .proj-synckit-new-key-heading { margin: 0 0 var(--gap-peer) 0; font-weight: 500; color: var(--danger); } .proj-synckit-create-status--error { color: var(--danger); margin-top: var(--gap-peer); } .proj-synckit-create-status--reset { margin-top: var(--gap-peer); } /* =========================================== ITEM PAGE (replaces inline styles in pages/item.html) =========================================== */ .item-page .breadcrumb { display: flex; justify-content: space-between; align-items: center; } .item-page .breadcrumb-edit-link { font-size: var(--text-note); color: var(--content); } .item-page .video-player { width: 100%; max-height: 600px; background: var(--primary-dark); } .item-page .item-cover-img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block; } .item-page .bundle-notice-inline { background: var(--surface-sunken); padding: var(--gap-section); } .item-page .bundle-notice-title { font-weight: bold; margin-bottom: var(--gap-peer); } .item-page .bundle-notice-desc { opacity: 0.8; font-size: var(--text-note); } .item-page .bundle-notice-entry { margin-top: var(--gap-section); } .item-page .bundle-notice-entry a { font-weight: bold; } .item-page .bundle-notice-price { opacity: 0.7; } .item-page .bundle-notice-empty { margin-top: var(--gap-peer); opacity: 0.7; font-size: var(--text-note); } .item-page .promo-details { margin-bottom: var(--gap-section); font-size: var(--text-note); } .item-page .promo-summary { cursor: pointer; opacity: 0.7; } .item-page .promo-form { display: flex; gap: var(--gap-peer); align-items: center; margin-top: var(--gap-peer); } .item-page .promo-input { flex: 1; padding: var(--gap-peer) var(--gap-group); font-size: var(--text-note); } .item-page .action-row { margin-top: var(--gap-section); } .item-page .action-row-tight { margin-top: var(--gap-peer); } .item-page .full-width-btn { width: 100%; font-size: var(--text-note); } .item-page .license-preset-name { margin-bottom: var(--gap-section); } .item-page .license-summary { cursor: pointer; opacity: 0.7; font-size: var(--text-note); } .item-page .license-text { white-space: pre-wrap; font-family: var(--font-sans); font-size: var(--text-note); margin-top: var(--gap-section); padding: var(--gap-section); background: var(--surface-sunken); } .item-page .license-download { margin-top: var(--gap-section); } .item-page .license-download a { font-size: var(--text-note); color: var(--content); } .item-page .bundle-list-entry { margin-top: var(--gap-peer); } .item-page .footer-links { margin-top: var(--gap-peer); } /* =========================================== JOIN COMPLETE STEP (replaces inline styles in wizards/steps/join/complete.html) =========================================== */ .join-complete-intro { margin-bottom: var(--gap-pane); } .join-complete-choices { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-section); max-width: 500px; } .join-complete-choice { text-decoration: none; color: inherit; display: block; } .join-complete-card { background: var(--surface-sunken); padding: var(--gap-section); text-align: center; border: 2px solid transparent; transition: border-color 0.15s; } .join-complete-choice:hover .join-complete-card, .join-complete-card--active { border-color: var(--content); } .join-complete-card-title { font-family: var(--font-display); font-weight: bold; font-size: var(--text-lead); margin-bottom: var(--gap-peer); } .join-complete-card-desc { font-size: var(--text-note); opacity: 0.7; margin: 0; } .join-complete-footnote { font-size: var(--text-note); opacity: 0.5; margin-top: var(--gap-section); text-align: center; } /* =========================================== PROMO CODES LIST (replaces inline styles in partials/promo_codes_list.html) =========================================== */ .promo-codes-row--expired { opacity: 0.5; } .promo-codes-row--pending { opacity: 0.7; } .promo-codes-schedule { font-size: var(--text-note); } .promo-codes-schedule-pending { color: var(--warning); } .promo-codes-schedule-expired { color: var(--danger); } .promo-codes-schedule-none { opacity: 0.5; } .promo-codes-actions { white-space: nowrap; } .promo-codes-edit-btn { font-size: var(--text-fine); } .promo-codes-edit-row { background: var(--surface-sunken); } .promo-codes-edit-cell { padding: var(--gap-section); } .promo-codes-edit-form { display: flex; gap: var(--gap-section); align-items: end; flex-wrap: wrap; } .promo-codes-edit-label { font-size: var(--text-fine); display: block; margin-bottom: var(--gap-bound); } .promo-codes-edit-save { font-size: var(--text-note); } .promo-codes-bulk-row { margin-top: var(--gap-section); } .promo-codes-bulk-btn { font-size: var(--text-note); opacity: 0.7; } /* =========================================== USER MEDIA TAB (replaces inline styles in partials/tabs/user_media.html) =========================================== */ .user-media-intro { margin-bottom: var(--gap-section); } .user-media-upload { border: 2px dashed var(--border); padding: var(--gap-pane); margin-bottom: var(--gap-pane); text-align: center; background: var(--surface-overlay); } .user-media-upload--dragover { border-color: var(--action); } .user-media-upload-row { margin-bottom: var(--gap-section); } .user-media-upload-label { display: inline-block; font-size: var(--text-note); margin-right: var(--gap-section); } .user-media-upload-folder-input { padding: var(--gap-bound); font-size: var(--text-note); width: 140px; margin-left: var(--gap-bound); } .user-media-upload-progress { margin-top: var(--gap-section); } .user-media-upload-status { font-size: var(--text-note); margin-bottom: var(--gap-bound); } .user-media-upload-status--ok { color: var(--success); } .user-media-upload-status--err { color: var(--danger); } .user-media-folders { margin-bottom: var(--gap-section); display: flex; gap: var(--gap-peer); flex-wrap: wrap; align-items: center; } .user-media-folders-label { font-size: var(--text-note); opacity: 0.7; } .user-media-folders-btn { font-size: var(--text-fine); } .user-media-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: var(--gap-section); } .user-media-card { background: var(--surface-overlay); border: 1px solid var(--border); padding: var(--gap-section); position: relative; } .user-media-card-thumb { width: 100%; height: 120px; overflow: hidden; margin-bottom: var(--gap-peer); display: flex; align-items: center; justify-content: center; background: var(--surface-sunken); } .user-media-card-thumb--video { font-size: var(--text-title); opacity: 0.4; } .user-media-card-img { max-width: 100%; max-height: 120px; object-fit: contain; } .user-media-card-name { font-size: var(--text-fine); word-break: break-all; margin-bottom: var(--gap-bound); } .user-media-card-meta { font-size: var(--text-fine); opacity: 0.6; margin-bottom: var(--gap-peer); } .user-media-card-actions { display: flex; gap: var(--gap-bound); } .user-media-card-btn { font-size: var(--text-fine); padding: var(--gap-bound) var(--gap-peer); } /* =========================================== ITEM VERSION UPLOAD (replaces inline styles in partials/item_version_upload.html) =========================================== */ .item-version-upload-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-section); } /* Where one slot's own work has got to, in the three words `Progress` emits. Here rather than in makeover because the hook is a data attribute `quasi-webview` writes rather than a class makeover names, and this is its only consumer. A second host wanting it is the reason to move it. */ .field-repeat-slot[data-repeat-progress="working"] { opacity: 0.75; } .field-repeat-slot[data-repeat-progress="done"] { opacity: 0.55; } .field-repeat-slot[data-repeat-progress="failed"] { border-left: 2px solid var(--danger); padding-left: var(--gap-peer); } .item-version-upload-speed { font-size: var(--text-fine); opacity: 0.6; margin-top: var(--gap-bound); } /* =========================================== INSERTION LIST (replaces inline styles in partials/insertion_list.html) =========================================== */ .insertion-list-heading { font-family: var(--font-mono); font-size: var(--text-body); margin-bottom: var(--gap-section); } .insertion-list-toolbar { margin-bottom: var(--gap-section); } .insertion-list-upload { font-family: var(--font-mono); } .insertion-list-table { width: 100%; font-family: var(--font-sans); } .insertion-list-table th { text-align: left; font-family: var(--font-mono); font-size: var(--text-note); } .insertion-list-table th.insertion-list-th-actions { text-align: right; } .insertion-list-table .insertion-list-actions { text-align: right; } .insertion-list-table .insertion-list-action-btn { font-family: var(--font-mono); } /* =========================================== PROJECT MEMBERS TAB (replaces inline styles in partials/tabs/project_members.html) =========================================== */ .proj-members-summary { background: var(--surface-sunken); padding: var(--gap-section); margin-bottom: var(--gap-section); } .proj-members-summary-row { display: flex; justify-content: space-between; align-items: center; } .proj-members-stat { font-size: var(--text-head); font-weight: bold; } .proj-members-add { margin-bottom: var(--gap-page); } .proj-members-add-grid { display: grid; grid-template-columns: 1fr auto auto; gap: var(--gap-section); align-items: end; } .proj-members-field-label { font-size: var(--text-note); display: block; margin-bottom: var(--gap-bound); } .proj-members-add-result { margin-top: var(--gap-peer); } .proj-members-name-link { color: inherit; } .proj-members-split-cell { font-weight: bold; } /* =========================================== PLACEMENT LIST (replaces inline styles in partials/placement_list.html) =========================================== */ .placement-list-heading { font-family: var(--font-mono); font-size: var(--text-body); margin-bottom: var(--gap-section); } .placement-list-table { width: 100%; font-family: var(--font-sans); margin-bottom: var(--gap-section); } .placement-list-table th { text-align: left; font-family: var(--font-mono); font-size: var(--text-note); } .placement-list-table th.placement-list-th-actions { text-align: right; } .placement-list-table .placement-list-actions { text-align: right; } .placement-list-table .placement-list-remove { font-family: var(--font-mono); } .placement-list-form { display: flex; gap: var(--gap-peer); align-items: flex-end; flex-wrap: wrap; } .placement-list-label { display: block; font-family: var(--font-mono); font-size: var(--text-fine); margin-bottom: var(--gap-bound); } .placement-list-add { font-family: var(--font-mono); } /* =========================================== USER SYNCKIT TAB (replaces inline styles in partials/tabs/user_synckit.html) =========================================== */ .user-synckit-create { margin-bottom: var(--gap-pane); } .user-synckit-create-body { padding: var(--gap-section); background: var(--surface-overlay); border: 1px solid var(--border); } .user-synckit-create-form { display: flex; flex-direction: row; gap: var(--gap-section); align-items: flex-end; } .user-synckit-create-form label { display: block; font-size: var(--text-note); margin-bottom: var(--gap-bound); } .user-synckit-create-form input[type="text"], .user-synckit-create-form select { padding: var(--gap-peer); font-size: var(--text-note); } .user-synckit-create-form input[type="text"] { width: 220px; } .user-synckit-create-form select { width: 180px; } .user-synckit-code { font-size: var(--text-fine); } .user-synckit-hint { font-size: var(--text-fine); margin-left: var(--gap-bound); } .user-synckit-inline-btn { margin-left: var(--gap-peer); padding: var(--gap-bound) var(--gap-peer); font-size: var(--text-fine); } .user-synckit-row-btn { padding: var(--gap-bound) var(--gap-peer); font-size: var(--text-fine); } .user-synckit-row-btn + .user-synckit-row-btn { margin-left: var(--gap-bound); } .user-synckit-status-active { color: var(--success); } .user-synckit-status-inactive { color: var(--danger); } .user-synckit-edit-btn { padding: var(--gap-bound) var(--gap-peer); font-size: var(--text-fine); } .user-synckit-create-error { color: var(--danger); margin-top: var(--gap-peer); } /* =========================================== TOTP (replaces inline styles in partials/totp_setup.html and totp_status.html) =========================================== */ /* Section wrapper between TOTP subsections (QR + backup codes + confirm, or regenerate + disable). */ .totp-section { margin-bottom: var(--gap-pane); } /* Confirm-setup section is separated from the backup codes by a top border. */ .totp-confirm { border-top: 1px solid var(--border); padding-top: var(--gap-section); } /* QR code container, centered above the manual-entry details. */ .totp-qr { text-align: center; margin-bottom: var(--gap-section); } .totp-qr img { max-width: 200px; image-rendering: pixelated; } /* Collapsible "Manual entry key" group. */ .totp-manual { margin-bottom: var(--gap-section); } .totp-manual summary { cursor: pointer; opacity: 0.7; font-size: var(--text-note); } .totp-manual-secret { display: block; margin-top: var(--gap-peer); word-break: break-all; font-size: var(--text-note); padding: var(--gap-peer); background: var(--surface-sunken); } /* Backup codes grid (rendered list of one-time codes). */ .backup-codes-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr)); gap: var(--gap-peer); } .backup-codes-grid code { padding: var(--gap-peer); background: var(--surface-sunken); text-align: center; font-size: var(--text-note); } /* Status row for the "Enabled" badge above the management forms. */ .totp-status-row { display: flex; align-items: center; gap: var(--gap-peer); margin-bottom: var(--gap-section); } /* Container where regenerated backup codes are swapped in via HTMX. */ .totp-regen-output { margin-top: var(--gap-section); } /* =========================================== DASHBOARD-USER SHELL (replaces inline styles in dashboards/dashboard-user.html) =========================================== */ .sandbox-banner { background: var(--action); color: var(--primary-light); padding: var(--gap-section) var(--gap-pane); text-align: center; font-family: var(--font-mono); font-size: var(--text-note); } .sandbox-banner-link { color: var(--primary-light); text-decoration: underline; margin-left: var(--gap-peer); } .account-status-actions { display: flex; gap: var(--gap-section); flex-wrap: wrap; margin-top: var(--gap-section); } .suspension-wrap { margin-bottom: var(--gap-section); } .password-warning-banner { margin-bottom: var(--gap-section); padding: var(--gap-section); background: color-mix(in oklch, var(--warning) 14%, var(--surface-page)); border: 1px solid var(--warning); font-size: var(--text-body); } .dash-user-header-links { margin-bottom: var(--gap-peer); display: flex; gap: var(--gap-pane); } .dash-user-header-link { font-size: var(--text-note); opacity: 0.7; } .checklist-recovery { padding: var(--gap-section) 0; text-align: right; } .checklist-recovery-link { font-size: var(--text-note); opacity: 0.7; } /* =========================================== SUSPENSION BANNER (replaces inline styles in partials/suspension_banner.html) =========================================== */ .suspension-banner { background: color-mix(in oklch, var(--danger) 10%, var(--surface-page)); border: 1px solid var(--danger); padding: var(--gap-pane); margin-bottom: var(--gap-pane); } .suspension-banner-title { margin: 0 0 var(--gap-peer) 0; color: var(--danger); } .suspension-banner-reason { font-size: var(--text-note); margin: 0 0 var(--gap-section) 0; } .suspension-banner-denial { background: var(--surface-overlay); padding: var(--gap-section); margin-bottom: var(--gap-section); font-size: var(--text-note); } .suspension-banner-denial-response { margin: var(--gap-bound) 0 0 0; } .suspension-banner-denial-hint { margin: var(--gap-peer) 0 0 0; opacity: 0.7; } .suspension-banner-pending { font-size: var(--text-note); opacity: 0.7; margin: 0; } .suspension-banner-appeal { margin-top: var(--gap-peer); } .suspension-banner-appeal-summary { cursor: pointer; font-size: var(--text-note); } .suspension-banner-appeal-form { margin-top: var(--gap-section); } .suspension-banner-appeal-text { width: 100%; margin-bottom: var(--gap-peer); font-size: var(--text-note); } .suspension-banner-appeal-submit { font-size: var(--text-note); } .suspension-banner-export { margin-top: var(--gap-section); } .suspension-banner-export-link { font-size: var(--text-note); } /* =========================================== REPORT MODAL (replaces inline styles in partials/report_modal.html) =========================================== */ .report-modal-content { background: var(--surface-page); padding: var(--gap-page); width: 90%; max-width: 480px; max-height: 90vh; overflow-y: auto; } .report-modal-title { font-size: var(--text-subhead); margin: 0; } .report-modal-fieldset { border: none; padding: 0; margin: 0 0 var(--gap-section) 0; } .report-modal-legend { font-size: var(--text-note); font-weight: 600; margin-bottom: var(--gap-peer); } .report-modal-option { display: block; margin-bottom: var(--gap-peer); cursor: pointer; } .report-modal-details { margin-bottom: var(--gap-section); } .report-modal-details-label { display: block; font-size: var(--text-note); margin-bottom: var(--gap-bound); } .report-modal-textarea { width: 100%; font-size: var(--text-note); } .report-modal-actions { display: flex; gap: var(--gap-peer); justify-content: flex-end; } /* =========================================== LIBRARY COLLECTIONS TAB (partials/tabs/library_collections.html) =========================================== */ .badge.is-faded { opacity: 0.5; } .lib-coll-new { margin-top: var(--gap-pane); } .lib-coll-new-summary { cursor: pointer; font-weight: bold; } .lib-coll-new-form { margin-top: var(--gap-section); } .lib-coll-wishlist-heading { font-size: var(--text-lead); margin-top: var(--gap-page); margin-bottom: var(--gap-section); opacity: 0.8; } .lib-coll-wishlist-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; } .lib-coll-wishlist-table { min-width: 500px; } .lib-coll-row-actions { white-space: nowrap; } .lib-coll-row-actions .lib-coll-cart-btn { margin-right: var(--gap-bound); } /* =========================================== USER ANALYTICS TAB (partials/tabs/user_analytics.html) =========================================== */ .analytics-export-link { margin-left: var(--gap-section); } .analytics-range-heading { font-size: var(--text-lead); margin: 0; } .analytics-section--comparison { margin-bottom: var(--gap-page); } .analytics-section--comparison h2 { margin-bottom: var(--gap-section); } .analytics-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; } .analytics-table { min-width: 500px; } .analytics-revenue-cell { display: flex; align-items: center; gap: var(--gap-peer); } .analytics-revenue-bar { width: var(--fill, 0%); height: 10px; min-width: 2px; max-width: 80px; background: var(--action); } /* =========================================== ITEM EMBED TAB (templates/partials/tabs/item_embed.html) =========================================== */ .embed-intro { opacity: 0.7; font-size: var(--text-note); margin-bottom: var(--gap-pane); } .embed-option { margin-bottom: var(--gap-pane); padding: var(--gap-section); border: 1px solid var(--border); border-radius: var(--radius-panel); } .embed-option h4 { margin-bottom: var(--gap-bound); font-size: var(--text-body); } .embed-option-desc { font-size: var(--text-note); opacity: 0.7; margin-bottom: var(--gap-peer); } .embed-preview { margin: var(--gap-section) 0; overflow: hidden; } .embed-iframe { border: none; border-radius: var(--radius-control); } .embed-layout-toggle { font-size: var(--text-note); margin-bottom: var(--gap-peer); display: flex; gap: var(--gap-section); } .embed-layout-toggle label { cursor: pointer; display: flex; align-items: center; gap: var(--gap-bound); } .embed-code-row { display: flex; align-items: center; gap: var(--gap-peer); } .embed-snippet { flex: 1; padding: var(--gap-peer) var(--gap-section); background: var(--surface-overlay); border-radius: var(--radius-control); font-size: var(--text-fine); overflow-x: auto; white-space: nowrap; font-family: var(--font-mono); border: 1px solid var(--border); } .copy-btn { padding: 6px 12px; font-size: var(--text-fine); background: var(--action); color: var(--primary-light); border: none; border-radius: var(--radius-control); cursor: pointer; white-space: nowrap; } .copy-btn:hover { opacity: 0.9; } /* =========================================== ADMIN NAV (templates/partials/admin_nav.html) =========================================== */ .admin-nav { display: flex; gap: var(--gap-peer); margin-bottom: var(--gap-pane); flex-wrap: wrap; font-family: var(--font-mono); font-size: var(--text-note); } .admin-nav a { padding: var(--gap-bound) var(--gap-section); text-decoration: none; } /* Admin nav items and filter-bar toggles are .btn-primary / .btn-secondary, toggled by the templates to mark the current page or active filter. Colour and depth come from the button recipe; only the tighter admin metrics and the active weight are stated here. */ .admin-nav a.btn-primary, .filter-bar button.btn-primary { font-weight: 700; } .admin-nav a.btn-secondary:hover, .filter-bar button.btn-secondary:hover { color: var(--content); } /* =========================================== VIDEO PLAYER PAGE (templates/pages/video_player.html) =========================================== */ .video-cover-img { width: 100%; display: block; background: var(--primary-dark); } .video-cover-placeholder { width: 100%; aspect-ratio: 16 / 9; background: var(--primary-dark); display: flex; align-items: center; justify-content: center; color: var(--content-muted); } .video-store-cta { margin: var(--gap-page) 0; padding: var(--gap-pane); background: var(--surface-sunken); text-align: center; } .video-cta-lead { font-size: var(--text-lead); margin-bottom: var(--gap-section); } .video-cta-price { font-size: var(--text-head); margin-bottom: var(--gap-section); } .video-cta-fineprint { font-size: var(--text-note); opacity: 0.7; margin-top: var(--gap-section); } .video-library-status { font-family: var(--font-mono); color: var(--content-muted); } /* =========================================== LIBRARY LOCKED PAGE (templates/pages/library_locked.html) =========================================== */ .library-locked-byline { opacity: 0.7; } .library-locked-cover { max-width: 320px; margin: var(--gap-section) 0; /* Reserve the space before the image loads (audit Run 17 Frontend). */ aspect-ratio: 1 / 1; object-fit: cover; } .library-locked-purchase { margin-top: var(--gap-page); } .library-locked-lead { opacity: 0.85; } .library-locked-actions { margin-top: var(--gap-pane); display: flex; gap: var(--gap-section); flex-wrap: wrap; } .library-locked-bundles { margin-top: var(--gap-pane); } .library-locked-bundles-title { font-weight: bold; } .library-locked-bundle { margin-top: var(--gap-peer); } .library-locked-bundle-price { opacity: 0.7; } /* =========================================== BLOG (replaces inline styles in project_blog.html and dashboard-blog-editor.html) =========================================== */ .blog-empty-state { padding: var(--gap-page) 0; } .blog-empty-hint { opacity: 0.7; font-size: var(--text-note); margin-top: var(--gap-peer); } .blog-post-title-link { font-weight: bold; } .blog-post-actions { display: flex; gap: var(--gap-peer); } /* Blog editor dashboard (templates/dashboards/dashboard-blog-editor.html). */ .blog-editor h1 { font-size: var(--text-title); margin-bottom: var(--gap-section); text-align: left; } .blog-editor .editor-form { max-width: 800px; } .blog-editor .editor-form .form-group { margin-bottom: var(--gap-section); } .blog-editor .editor-form textarea { font-family: var(--font-mono); font-size: var(--text-note); min-height: 400px; resize: vertical; } .blog-editor-slug-spinner { font-size: var(--text-note); } .blog-editor-actions { display: flex; gap: var(--gap-section); align-items: center; } .blog-editor-status { margin-top: var(--gap-peer); } /* =========================================== AUDIO PLAYER (replaces inline styles in pages/audio_player.html) =========================================== */ .audio-store-cta { margin: var(--gap-page) 0; padding: var(--gap-pane); background: var(--surface-sunken); text-align: center; } .audio-store-cta .audio-access-msg { font-size: var(--text-lead); margin-bottom: var(--gap-section); } .audio-store-cta .audio-price { font-size: var(--text-head); margin-bottom: var(--gap-section); } .audio-store-cta .audio-fee-note { font-size: var(--text-note); opacity: 0.7; margin-top: var(--gap-section); } .audio-library-status { font-family: var(--font-mono); color: var(--content-muted); } /* =========================================== SECTIONS WIZARD STEP (templates/wizards/steps/item/sections.html) Parallels .psection-row used by item_details + project-sections.js, but isolated so wizard markup can evolve independently. =========================================== */ .section-row { display: flex; align-items: center; gap: var(--gap-section); padding: var(--gap-group) 0; border-bottom: 1px solid var(--border); } .section-row-title { flex: 1; font-weight: bold; } .section-row-length { font-size: var(--text-fine); opacity: 0.6; } .section-row .section-delete-btn { padding: var(--gap-bound) var(--gap-group); font-size: var(--text-fine); } .section-add-body { margin-top: var(--gap-section); } .wizard-actions { margin-top: var(--gap-pane); } /* =========================================== PROJECT SUBSCRIPTIONS TAB (templates/partials/tabs/project_subscriptions.html) =========================================== */ .subs-connect-info { margin-bottom: var(--gap-pane); padding: var(--gap-section); } .subs-new-tier { margin-bottom: var(--gap-page); } .tier-row-desc { font-size: var(--text-note); opacity: 0.7; margin-top: var(--gap-bound); } .tier-action-btn { font-size: var(--text-note); padding: var(--gap-bound) var(--gap-group); } .subs-members-bar { margin-top: var(--gap-page); display: flex; justify-content: space-between; align-items: center; } /* =========================================== LIBRARY CONSUMPTION PAGES =========================================== Shared styles for the library-side consumption surfaces: text_reader.html, library_text.html (.article-page), library_downloads.html (.library-page), library_audio.html / library_video.html (.media-container + helpers). The .article-page and .library-page sections higher up in this file are activated by body classes set in the templates. */ /* Faded excerpt text on the public store-page text reader. */ .article-page .article-body--excerpt { opacity: 0.85; } /* Store-page call-to-action block (text_reader.html). */ .article-page .store-cta { margin: var(--gap-page) 0; padding: var(--gap-pane); background: var(--surface-sunken); text-align: center; } .article-page .store-cta-lead { font-size: var(--text-lead); margin-bottom: var(--gap-section); } .article-page .store-cta-price { font-size: var(--text-head); margin-bottom: var(--gap-section); } .article-page .store-cta-note { font-size: var(--text-note); opacity: 0.7; margin-top: var(--gap-section); } .article-page .store-cta .library-status { font-family: var(--font-mono); color: var(--content-muted); } /* Library back-link breadcrumb shared by the media library pages. */ .media-container .library-back { font-size: var(--text-note); opacity: 0.7; margin: var(--gap-section) 0; } .media-container .library-back a { color: var(--content); } /* Source-files download list under audio/video library pages. The .library-page version exists higher up; this block scopes the same look under .media-container for audio/video. */ .media-container .library-downloads { background: var(--surface-overlay); padding: var(--gap-pane); margin-top: var(--gap-page); } .media-container .library-downloads h3 { font-size: var(--text-lead); margin-bottom: var(--gap-section); } .media-container .download-row { display: flex; align-items: center; gap: var(--gap-section); padding: var(--gap-peer) 0; border-bottom: 1px solid var(--border); } .media-container .download-row:last-child { border-bottom: none; } .media-container .download-version { min-width: 4em; font-family: var(--font-mono); font-size: var(--text-note); } .media-container .download-label { flex: 1; } .media-container .download-label--empty { flex: 1; opacity: 0.5; } .media-container .download-size { font-size: var(--text-note); opacity: 0.6; min-width: 5em; text-align: right; } /* Compact download button used in both library_downloads.html and media library pages. */ .btn-download-compact { padding: var(--gap-peer) var(--gap-section); font-size: var(--text-note); } /* Faded "no label" placeholder on library_downloads.html download rows. */ .library-page .download-label--empty { opacity: 0.5; } /* Library-downloads description
summary + body. */ .library-page .lib-summary { cursor: pointer; font-family: var(--font-display); font-size: var(--text-subhead); } .library-page .lib-summary-body { margin-top: var(--gap-section); } /* License section on library_downloads.html. */ .library-page .lib-license-name { margin-bottom: var(--gap-section); } .library-page .lib-license-download { font-size: var(--text-note); color: var(--content); } /* Footer below the item-footer (was inline on library_downloads.html). */ .library-page .item-footer-sub { margin-top: var(--gap-peer); } /* library_text.html footer: a terse in-page footer for the library's own text view, unrelated to base.html's site-footer. */ .article-page .lib-text-footer { text-align: center; padding: var(--gap-page); font-size: var(--text-note); opacity: 0.6; border-top: 1px solid var(--border); } .article-page .lib-text-footer a { color: var(--content); } /* Media player play/pause icon initial state. The JS in media-player.js toggles via element.style.display directly, so we must NOT use !important here, element.style would still beat a normal-priority declaration, but !important in the stylesheet would defeat that. */ .media-icon-hidden { display: none; } /* Video element fills its .video-display parent. .video-display already provides a black background. */ .video-display video { width: 100%; } /* Cover image inside .cover-art on library_audio.html, the parent .cover-art already sets aspect ratio and centering; the inline width/aspect-ratio/object-fit was redundant with .cover-art img. */ /* =========================================== USER DASHBOARD TABS (support / sessions / buyer contacts) =========================================== */ /* Sessions tab (templates/partials/tabs/user_sessions.html). */ .sessions-tab .sessions-table { width: 100%; } .sessions-tab .device-cell { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Buyer contacts tab (templates/partials/tabs/buyer_contacts.html). */ .buyer-contacts .contacts-table { min-width: 500px; } /* =========================================== LIBRARY TABS Shared classes for the library-dashboard tab partials: library_wishlists, library_contacts, library_purchases, library_subscriptions. Migrated from inline styles. =========================================== */ /* Tables in library tabs need a minimum width so columns stay readable while the outer container scrolls horizontally on narrow viewports. */ /* Empty-state hint paragraph (smaller, slightly faded). */ .library-tab-empty-hint { font-size: var(--text-note); opacity: 0.7; margin-bottom: var(--gap-section); } /* Compact row-action button (wishlist Add to Cart / Remove, etc.). */ .library-filter-wrap { margin-bottom: var(--gap-section); } /* Purchases table "Open" action link + context menu trigger group. */ .library-row-actions { display: flex; align-items: center; gap: var(--gap-peer); } .library-row-open { font-size: var(--text-fine); padding: var(--gap-bound) var(--gap-section); text-decoration: none; white-space: nowrap; } /* Section sub-heading inside purchases tab (e.g. "Subscriptions"). */ .library-tab-subheading { font-size: var(--text-lead); margin-top: var(--gap-page); margin-bottom: var(--gap-section); opacity: 0.8; } /* Inline-block button styled as a link target on empty-state CTAs. */ .library-tab-cta { display: inline-block; text-decoration: none; } /* Context menu (dropdown) on each purchase row. */ .context-menu-wrapper { position: relative; } .context-menu-btn { background: none; border: none; cursor: pointer; padding: var(--gap-peer); font-size: var(--text-subhead); line-height: 1; color: var(--content-muted); border-radius: var(--radius-control); } .context-menu-btn:hover { background: var(--surface-sunken); color: var(--content); } .context-menu { display: none; position: absolute; right: 0; top: 100%; background: var(--surface-overlay); border: 1px solid var(--border); box-shadow: var(--elevation-overlay); min-width: 160px; z-index: var(--z-context); } .context-menu.open { display: block; } .context-menu-item { display: block; width: 100%; padding: var(--gap-section); text-align: left; background: none; border: none; font-family: var(--font-sans); font-size: var(--text-note); color: var(--content); cursor: pointer; text-decoration: none; } .context-menu-item:hover { background: var(--surface-sunken); } .context-menu-item.danger { color: var(--danger); } /* Inline license-key code chip shown beneath a purchase date. */ .license-key-inline { margin-top: var(--gap-bound); } .key-code-small { font-size: var(--text-fine); padding: var(--gap-bound) var(--gap-peer); background: var(--surface-sunken); border-radius: var(--radius-control); cursor: pointer; user-select: all; } .key-code-small:hover { background: var(--border); } /* Library row title link reads as plain text until hovered. */ .library-title-link:hover { text-decoration: underline; } /* =========================================== ADMIN ENTRIES (replaces inline styles in partials/admin_user_entries.html, partials/admin_waitlist_entries.html, partials/admin_appeal_entries.html) =========================================== */ /* (`.badge-active` / `.badge-trusted` removed in wave 2 tier B2. They were a second, ad-hoc spelling of what data-tone="success" already says, and the admin entries take the tone now.) */ /* "Trust" toggle button sits next to a Trusted badge. */ .admin-entries-trust-btn { margin-left: var(--gap-bound); } /* Waitlist pitch cell, narrow body text. */ .admin-entries-pitch { font-size: var(--text-note); max-width: 300px; } .admin-entries-pitch-empty { opacity: 0.5; font-style: italic; } .admin-entries-pitch-inviter { margin-top: var(--gap-bound); } /* Appeal text columns. */ .admin-entries-reason { font-size: var(--text-note); max-width: 200px; } .admin-entries-appeal { font-size: var(--text-note); max-width: 300px; } /* Decide form textarea + stacked action buttons. */ .admin-entries-decide-textarea { width: 200px; } .admin-entries-decide-actions { display: flex; flex-direction: column; gap: var(--gap-bound); } /* Pagination row at the bottom of admin entry tables. */ .admin-entries-pagination { display: flex; justify-content: center; align-items: center; gap: var(--gap-section); padding: var(--gap-section) 0; } /* =========================================== ITEM TABS (item_settings, item_sales, item_overview partials) =========================================== */ /* Schedule form is hidden until "Schedule" button is clicked. JS toggles the `.hidden` utility class. */ .item-settings-schedule-form { margin-top: var(--gap-section); } .item-overview-embed { margin-top: var(--gap-pane); } .item-overview-embed > summary { cursor: pointer; font-weight: bold; font-size: var(--text-lead); } /* =========================================== ITEM TEXT EDITOR (partials/item_text_editor.html) =========================================== */ .text-editor-actions { margin-top: var(--gap-section); } /* =========================================== PROJECT ANALYTICS TAB (partials/tabs/project_analytics.html) =========================================== */ .tab-docs-extra { margin-left: var(--gap-section); } .analytics-tab-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--gap-section); } .analytics-tab-header h2 { font-size: var(--text-lead); margin: 0; } .analytics-empty-block { text-align: center; padding: var(--gap-page) var(--gap-section); opacity: 0.6; } /* =========================================== RECEIPT PAGE INLINE FRAGMENTS (pages/receipt.html) =========================================== */ .receipt-page .receipt-brand { opacity: 0.6; font-size: var(--text-note); } .receipt-page .receipt-meta { text-align: right; } .receipt-page .receipt-meta-line { font-family: var(--font-mono); font-size: var(--text-note); opacity: 0.6; } .receipt-page .receipt-meta-sub { font-family: var(--font-mono); font-size: var(--text-fine); opacity: 0.4; margin-top: var(--gap-bound); } .receipt-page .print-btn { margin-top: var(--gap-section); font-size: var(--text-note); } /* =========================================== IMPORT PAGE INLINE FRAGMENTS (dashboards/dashboard-import.html) =========================================== */ .import-page .import-preview-label, .import-page .import-mapping-label, .import-page .import-progress-label { font-family: var(--font-mono); font-size: var(--text-note); margin-bottom: var(--gap-peer); } .import-page .import-mapping-label { margin-bottom: var(--gap-section); } .import-page .import-progress-label { font-size: var(--text-note); } .import-page .import-start-btn { margin-top: var(--gap-section); } .import-page .import-history-heading { font-size: var(--text-subhead); margin-bottom: var(--gap-section); } /* =========================================== SLUG STATUS PARTIAL (partials/slug_status.html) =========================================== */ .slug-status { font-size: var(--text-note); } .slug-status.available { color: var(--success); } .slug-status.taken { color: var(--danger); } .slug-suggestions { font-size: var(--text-note); display: block; margin-top: var(--gap-bound); } .slug-suggestion-link { margin-right: var(--gap-peer); } /* =========================================== STRIPE DISCLAIMER PAGE (pages/stripe_disclaimer.html) =========================================== */ .stripe-disclaimer-page .container { max-width: 700px; margin: var(--gap-pane) auto; padding: 0 var(--gap-page); } .stripe-disclaimer-page .stripe-disclaimer-title { text-align: center; } .stripe-disclaimer-page .tagline { font-size: var(--text-note); opacity: 0.7; margin-bottom: var(--gap-page); text-align: center; } .stripe-disclaimer-page h2 { font-size: var(--text-head); margin-bottom: var(--gap-pane); } .stripe-disclaimer-page .stripe-disclaimer-lead { margin-bottom: var(--gap-pane); opacity: 0.8; } .stripe-disclaimer-page .section { margin-bottom: var(--gap-page); } .stripe-disclaimer-page .section h3 { font-size: var(--text-lead); margin-bottom: var(--gap-section); font-family: var(--font-mono); } .stripe-disclaimer-page .section ul { margin: 0; padding-left: var(--gap-section); } .stripe-disclaimer-page .section li { margin-bottom: var(--gap-peer); line-height: 1.5; } .stripe-disclaimer-page .stripe-disclaimer-fee-lead { margin-bottom: var(--gap-section); } .stripe-disclaimer-page .fee-example { background: var(--surface-page); padding: var(--gap-section); margin: var(--gap-section) 0; font-family: var(--font-mono); font-size: var(--text-note); } .stripe-disclaimer-page .fee-row { display: flex; justify-content: space-between; padding: var(--gap-bound) 0; } .stripe-disclaimer-page .fee-row.highlight { font-weight: bold; border-top: 1px solid var(--border); margin-top: var(--gap-peer); padding-top: var(--gap-peer); } .stripe-disclaimer-page .fee-row .zero { color: var(--content); } .stripe-disclaimer-page .stripe-disclaimer-note { font-size: var(--text-note); opacity: 0.8; } .stripe-disclaimer-page .acceptance { background: var(--surface-page); padding: var(--gap-section); margin: var(--gap-pane) 0; } .stripe-disclaimer-page .checkbox-group { display: flex; align-items: flex-start; gap: var(--gap-section); } .stripe-disclaimer-page .checkbox-group input[type="checkbox"] { margin-top: var(--gap-bound); flex-shrink: 0; } .stripe-disclaimer-page .checkbox-group label { line-height: 1.5; cursor: pointer; } .stripe-disclaimer-page .button-row { display: flex; gap: var(--gap-section); margin-top: var(--gap-pane); } .stripe-disclaimer-page .button-row button { flex: 1; } .stripe-disclaimer-page button:disabled { opacity: 0.5; cursor: not-allowed; } .stripe-disclaimer-page .note { font-size: var(--text-note); opacity: 0.6; margin-top: var(--gap-section); text-align: center; }