/* Admin component styles — uses --t-* theme tokens directly. */ @layer admin { /* ── Derived tokens ── */ :root { --admin-text-ghost: var(--admin-text-ghost); --admin-text-faintest: var(--admin-text-faintest); --admin-text-faint: var(--admin-text-faint); --admin-text-muted: var(--admin-text-muted); --admin-text-soft: var(--admin-text-soft); } /* ── Layout ── */ .admin-layout { display: grid; grid-template-columns: 0 1fr; height: 100%; min-height: 100vh; } .admin-layout-toggle { position: absolute; opacity: 0; pointer-events: none; } .admin-layout-content { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; grid-column: 2; min-width: 0; overflow-x: hidden; } .admin-sidebar-wrapper { grid-column: 1; grid-row: 1; z-index: 40; display: none; } /* When checkbox is checked, show sidebar overlay on mobile */ .admin-layout-toggle:checked ~ .admin-sidebar-wrapper { display: block; position: fixed; inset: 0; z-index: 40; } .admin-sidebar-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.3); cursor: pointer; } .admin-sidebar { position: relative; z-index: 1; width: 16rem; min-height: 100%; max-height: 100vh; max-height: 100dvh; overflow-y: auto; display: flex; flex-direction: column; background-color: var(--t-surface-sunken); } @media (min-width: 64em) { .admin-layout { grid-template-columns: 16rem 1fr; } .admin-sidebar-wrapper { display: block; position: relative; } .admin-sidebar { position: sticky; top: 0; } .admin-sidebar-overlay { display: none; } .admin-topbar { display: none; } } /* ── Top bar (mobile only) ── */ .admin-topbar { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem; background-color: var(--t-surface-base); border-bottom: 1px solid var(--t-surface-sunken); } .admin-topbar-title { flex: 1; font-size: 1.125rem; font-weight: 600; } /* ── Sidebar nav ── */ .admin-nav-group { & + & { margin-top: 0.75rem; } } .admin-nav-heading { display: block; padding: 0.25rem 0.75rem; font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: color-mix(in oklch, var(--t-text-primary) 45%, transparent); } .admin-nav { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.125rem; & li a, & li button { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.75rem; border-radius: 0.375rem; text-decoration: none; color: inherit; font-size: 0.875rem; transition: background-color 0.1s; cursor: pointer; background: none; border: none; width: 100%; text-align: start; &:hover { background-color: var(--t-border-default); } &.active { background-color: var(--t-border-default); font-weight: 600; } } } /* ── Buttons ── */ .admin-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; padding: 0.5rem 1rem; font-size: 0.875rem; font-weight: 500; line-height: 1.25rem; border-radius: 0.375rem; border: 1px solid transparent; cursor: pointer; text-decoration: none; white-space: nowrap; transition: background-color 0.1s, opacity 0.1s; background-color: var(--t-accent); color: var(--t-text-inverse); &:hover { opacity: 0.85; } &:disabled { opacity: 0.5; cursor: not-allowed; pointer-events: none; } } .admin-btn-primary { background-color: var(--t-accent); color: var(--t-text-inverse); & .admin-badge { background: color-mix(in oklch, var(--t-text-inverse) 90%, transparent); color: var(--t-accent); } } .admin-btn-soft { background-color: color-mix(in oklch, var(--t-accent) 12%, transparent); color: var(--t-accent); &:hover { background-color: color-mix(in oklch, var(--t-accent) 20%, transparent); opacity: 1; } } .admin-btn-ghost { background: none; color: inherit; &:hover { background-color: var(--t-surface-sunken); opacity: 1; } } .admin-btn-active { background-color: var(--t-surface-sunken); } .admin-btn-outline { background: none; color: inherit; border-color: var(--t-border-default); &:hover { background-color: var(--t-surface-sunken); opacity: 1; } } .admin-btn-sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; } .admin-btn-xs { padding: 0.125rem 0.375rem; font-size: 0.6875rem; } .admin-btn-block { width: 100%; justify-content: center; } .admin-btn-icon { padding: 0.5rem; aspect-ratio: 1; border-radius: 0.375rem; } .admin-btn-icon-round { padding: 0.25rem; aspect-ratio: 1; border-radius: 9999px; } /* ── Page header ── */ .admin-header { /* pb-4 was never defined in utilities — no padding in original */ } .admin-header-with-actions { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; } .admin-header-title { font-size: 1.125rem; font-weight: 600; line-height: 2rem; } .admin-header-subtitle { font-size: 0.875rem; line-height: 1.25rem; color: var(--admin-text-soft); } .admin-header-actions { flex: none; } /* ── Filter / tab row (below page header) ── */ .admin-filter-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 1.5rem; margin-bottom: 1rem; } .admin-filter-row-end { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem; margin-top: 1.5rem; margin-bottom: 1rem; } /* ── Back link (breadcrumb-style return link) ── */ .admin-back-link { font-size: 0.875rem; line-height: 1.25rem; font-weight: 400; color: var(--admin-text-muted); &:hover { text-decoration: underline; } } /* ── Cards ── */ .admin-card { background-color: var(--t-surface-base); border: 1px solid var(--t-surface-sunken); border-radius: 0.5rem; overflow: hidden; } .admin-card-body { padding: 1rem 1.25rem; } .admin-card-title { font-weight: 600; margin-bottom: 0.75rem; } .admin-card-actions { display: flex; gap: 0.5rem; justify-content: flex-end; padding-top: 0.75rem; border-top: 1px solid var(--t-surface-sunken); margin-top: 0.75rem; } /* Card layout helpers */ .admin-card-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; } .admin-card-content { flex: 1; min-width: 0; } .admin-card-subtitle { font-size: 0.875rem; color: var(--admin-text-soft); margin-top: 0.25rem; } .admin-card-meta { display: flex; flex-wrap: wrap; column-gap: 1rem; row-gap: 0.25rem; margin-top: 0.5rem; font-size: 0.875rem; color: var(--admin-text-muted); } .admin-card-toolbar { display: flex; align-items: center; gap: 0.5rem; } /* ── Empty states ── */ .admin-empty-state { text-align: center; padding: 3rem 1rem; } .admin-empty-state-icon { width: 4rem; height: 4rem; margin-inline: auto; margin-bottom: 1rem; color: var(--admin-text-ghost); } .admin-empty-state-title { font-size: 1.25rem; font-weight: 500; } .admin-empty-state-text { margin-top: 0.5rem; color: var(--admin-text-muted); max-width: 28rem; margin-inline: auto; } .admin-empty-state-actions { display: flex; justify-content: center; gap: 0.75rem; margin-top: 1.5rem; } /* ── Callout / info box ── */ .admin-callout { border-radius: 0.5rem; background: var(--t-surface-sunken); padding: 1rem; margin-bottom: 1.5rem; font-size: 0.875rem; } .admin-callout-title { font-weight: 500; margin-bottom: 0.5rem; } .admin-callout-list { list-style: decimal inside; & li + li { margin-top: 0.25rem; } } /* ── Inline status indicators ── */ .admin-status-success { color: var(--t-status-success, oklch(0.65 0.19 145)); display: flex; align-items: center; gap: 0.25rem; } .admin-status-error { color: var(--t-status-error, #dc2626); display: flex; align-items: center; gap: 0.25rem; } /* ── Form layout helpers ── */ .admin-form-narrow { max-width: 36rem; margin-top: 1.5rem; } .admin-form-actions { display: flex; gap: 0.5rem; margin-top: 1.5rem; } .admin-inline-group { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1.5rem; } /* ── Tables ── */ .admin-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; } .admin-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; & th { text-align: start; padding: 0.5rem 0.75rem; font-weight: 600; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--admin-text-muted); border-bottom: 1px solid var(--t-surface-sunken); } & td { padding: 0.5rem 0.75rem; border-bottom: 1px solid color-mix(in oklch, var(--t-surface-sunken) 50%, transparent); vertical-align: middle; } & tbody tr:last-child td { border-bottom: none; } } .admin-table-zebra tbody tr:nth-child(even) { background-color: color-mix(in oklch, var(--t-surface-sunken) 30%, transparent); } .admin-table-actions { width: 0; font-weight: 600; } .admin-table-actions-row { display: flex; gap: 1rem; } /* ── Forms ── */ .admin-fieldset { margin-bottom: 0.5rem; } .admin-label { display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 0.25rem; } .admin-input, .admin-select, .admin-textarea { display: block; width: 100%; padding: 0.5rem 0.75rem; font-size: 0.875rem; line-height: 1.5; color: var(--t-text-primary); background-color: var(--t-surface-base); border: 1px solid var(--t-border-input, var(--t-border-default)); border-radius: 0.375rem; transition: border-color 0.15s; &:focus { outline: none; border-color: var(--t-accent); box-shadow: 0 0 0 1px color-mix(in oklch, var(--t-accent) 20%, transparent); } } .admin-select { appearance: auto; } .admin-input-error { border-color: var(--t-status-error); border-width: 2px; &:focus { border-color: var(--t-status-error); box-shadow: 0 0 0 1px color-mix(in oklch, var(--t-status-error) 20%, transparent); } } .admin-checkbox { width: 1rem; height: 1rem; accent-color: var(--t-accent); vertical-align: middle; cursor: pointer; } .admin-checkbox-sm { width: 0.875rem; height: 0.875rem; } .admin-select-sm, .admin-input-sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; } /* ── Toggle ── */ .admin-toggle { appearance: none; width: 2.5rem; height: 1.25rem; background-color: var(--t-border-default); border-radius: 9999px; position: relative; cursor: pointer; transition: background-color 0.2s; vertical-align: middle; flex-shrink: 0; &::after { content: ""; position: absolute; top: 0.125rem; inset-inline-start: 0.125rem; width: 1rem; height: 1rem; background: white; border-radius: 9999px; transition: transform 0.2s; } &:checked { background-color: var(--t-accent); } &:checked::after { transform: translateX(1.25rem); } } .admin-toggle-sm { width: 2rem; height: 1rem; &::after { width: 0.75rem; height: 0.75rem; } &:checked::after { transform: translateX(1rem); } } /* ── Feedback ── */ .admin-banner { /* document flow — pushes content down, no overlay */ } /* Hide connection error banners during intentional navigation */ .navigating-away #flash-group { display: none; } .admin-alert { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.75rem 1rem; font-size: 0.875rem; line-height: 1.5; overflow-wrap: break-word; } .admin-alert-title { font-weight: 600; } .admin-alert-spacer { flex: 1; } .admin-alert-info { background-color: color-mix(in oklch, var(--t-status-info) 12%, var(--t-surface-base)); color: var(--t-status-info); border-bottom: 1px solid color-mix(in oklch, var(--t-status-info) 25%, var(--t-surface-base)); } .admin-alert-error { background-color: color-mix(in oklch, var(--t-status-error) 12%, var(--t-surface-base)); color: var(--t-status-error); border-bottom: 1px solid color-mix(in oklch, var(--t-status-error) 25%, var(--t-surface-base)); } .admin-alert-close { align-self: flex-start; cursor: pointer; opacity: 0.4; &:hover { opacity: 0.7; } } .admin-inline-feedback { display: inline-flex; align-items: center; gap: 0.375rem; font-size: 0.875rem; line-height: 1.5; } .admin-inline-feedback-saving { color: var(--admin-text-soft); } .admin-inline-feedback-saved { color: var(--t-status-success, oklch(0.55 0.15 145)); } .admin-inline-feedback-error { color: var(--t-status-error); font-weight: 600; } .admin-banner-warning { display: flex; align-items: center; gap: 0.75rem; padding: 0.625rem 1rem; font-size: 0.875rem; line-height: 1.5; background-color: color-mix(in oklch, var(--t-status-warning) 12%, var(--t-surface-base)); color: var(--t-text-body); border-bottom: 1px solid color-mix(in oklch, var(--t-status-warning) 30%, var(--t-surface-base)); & .size-5 { color: var(--t-status-warning); } & code { font-size: 0.8125rem; } } /* ── Modal ── */ .admin-modal { border: none; border-radius: 0.75rem; padding: 0; max-width: 32rem; width: calc(100% - 2rem); background-color: var(--t-surface-base); color: var(--t-text-primary); box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); &::backdrop { background: rgba(0, 0, 0, 0.4); } } .admin-modal-box { padding: 1.5rem; position: relative; } .admin-modal-close { position: absolute; inset-inline-end: 0.5rem; top: 0.5rem; } .admin-modal-actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 1.5rem; } /* ── Badge ── */ .admin-badge { display: inline-flex; align-items: center; padding: 0.125rem 0.5rem; font-size: 0.75rem; font-weight: 500; border-radius: 9999px; background-color: var(--t-surface-sunken); color: var(--admin-text-soft); } .admin-badge-sm { padding: 0 0.375rem; font-size: 0.625rem; } .admin-badge-info { background-color: color-mix(in oklch, var(--t-accent) 15%, transparent); color: var(--t-accent); } .admin-badge-accent { background-color: color-mix(in oklch, var(--t-status-success, #22c55e) 15%, transparent); color: var(--t-status-success, #16a34a); } .admin-badge-warning { background-color: color-mix(in oklch, var(--t-status-warning, #f59e0b) 15%, transparent); color: var(--t-status-warning, #b45309); } .admin-badge-neutral { background-color: var(--t-surface-sunken); color: var(--admin-text-muted); } /* ── Dropdown ── */ .admin-dropdown { position: relative; display: inline-block; & .admin-dropdown-content { display: none; position: absolute; inset-inline-end: 0; top: 100%; margin-top: 0.25rem; min-width: 12rem; background-color: var(--t-surface-base); border: 1px solid var(--t-surface-sunken); border-radius: 0.5rem; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); z-index: 50; padding: 0.25rem; list-style: none; } &:focus-within .admin-dropdown-content, &[open] .admin-dropdown-content { display: block; } } .admin-dropdown-content li a, .admin-dropdown-content li button { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.75rem; border-radius: 0.375rem; font-size: 0.875rem; color: var(--t-text-primary); text-decoration: none; cursor: pointer; background: none; border: none; width: 100%; text-align: left; &:hover { background-color: var(--t-surface-sunken); } } /* ── Spinner ── */ @keyframes admin-spin { to { transform: rotate(360deg); } } /* ── Divider ── */ .admin-divider { display: flex; align-items: center; gap: 1rem; color: var(--admin-text-faintest); font-size: 0.75rem; &::before, &::after { content: ""; flex: 1; height: 1px; background-color: var(--t-border-default); } } /* ── List ── */ .admin-list { list-style: none; padding: 0; margin: 0; } .admin-list-row { display: flex; gap: 1rem; padding: 0.75rem 0; border-bottom: 1px solid var(--t-surface-sunken); &:last-child { border-bottom: none; } } .admin-list-grow { flex: 1; } .admin-list-title { font-weight: 700; } /* ── Form error text ── */ .admin-error { display: flex; align-items: center; gap: 0.375rem; margin-top: 0.375rem; font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; color: var(--t-status-error); } .admin-error-icon { width: 1em; height: 1em; flex-shrink: 0; } /* ── Link ── */ .admin-link { color: var(--t-accent); text-decoration: underline; text-underline-offset: 0.125em; &:hover { opacity: 0.8; } } /* ── Range ── */ .admin-range { appearance: none; width: 100%; height: 0.375rem; background-color: var(--t-border-default); border-radius: 9999px; cursor: pointer; vertical-align: middle; &::-webkit-slider-thumb { appearance: none; width: 1rem; height: 1rem; background: var(--t-accent); border-radius: 9999px; border: 2px solid var(--t-surface-base); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); } &::-moz-range-thumb { width: 1rem; height: 1rem; background: var(--t-accent); border-radius: 9999px; border: 2px solid var(--t-surface-base); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); } } /* ── Alert outline ── */ .admin-alert-outline { background: none; color: var(--admin-text-soft); border: 1px solid var(--t-border-default); } /* ── Checklist banner (shown when arriving from the launch checklist) ── */ .admin-checklist-banner { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem; margin-bottom: 1.5rem; font-size: 0.875rem; line-height: 1.5; border-radius: 0.5rem; background-color: color-mix(in oklch, var(--t-status-info) 10%, var(--t-surface-base)); border: 1px solid color-mix(in oklch, var(--t-status-info) 20%, var(--t-surface-base)); & .admin-checklist-banner-icon { color: var(--t-status-info); flex-shrink: 0; } & .admin-checklist-banner-text { flex: 1; color: var(--t-text-secondary); } & .admin-checklist-banner-link { font-weight: 500; white-space: nowrap; } } /* ── Dashboard stats grid ── */ .admin-stats-grid { display: grid; grid-template-columns: repeat(1, 1fr); gap: 1rem; margin-top: 1.5rem; } @media (min-width: 640px) { .admin-stats-grid { grid-template-columns: repeat(3, 1fr); } } /* ── Analytics chart labels ── */ .analytics-y-labels, .analytics-x-labels { font-size: 0.6875rem; color: color-mix(in oklch, var(--t-text-primary) 55%, transparent); font-variant-numeric: tabular-nums; } [data-bars] > div { cursor: crosshair; } /* ── Settings sections ── */ .admin-settings { max-width: 42rem; } .admin-section { margin-top: 2.5rem; } .admin-section-header { display: flex; align-items: center; gap: 0.75rem; } .admin-section-title { font-size: 1.125rem; font-weight: 600; } .admin-section-desc { margin-top: 0.5rem; font-size: 0.875rem; color: var(--admin-text-muted); } .admin-section-body { margin-top: 1rem; } /* ── Status pills (inline badges in section headers) ── */ .admin-status-pill { display: inline-flex; align-items: center; gap: 0.25rem; border-radius: 9999px; padding: 0.25rem 0.5rem; font-size: 0.75rem; font-weight: 500; box-shadow: inset 0 0 0 1px var(--_pill-ring); } .admin-status-pill-green { --_pill-ring: rgb(22 163 74 / 0.2); background: #f0fdf4; color: #15803d; } .admin-status-pill-amber { --_pill-ring: rgb(217 119 6 / 0.1); background: #fffbeb; color: #b45309; } .admin-status-pill-blue { --_pill-ring: rgb(37 99 235 / 0.2); background: #eff6ff; color: #1d4ed8; } .admin-status-pill-red { --_pill-ring: rgb(220 38 38 / 0.2); background: #fef2f2; color: #b91c1c; } .admin-status-pill-purple { --_pill-ring: rgb(147 51 234 / 0.2); background: #faf5ff; color: #7e22ce; } .admin-status-pill-zinc { --_pill-ring: color-mix(in oklch, var(--t-text-primary) 10%, transparent); background: color-mix(in oklch, var(--t-surface-sunken) 50%, transparent); color: var(--admin-text-muted); } /* ── Definition lists (key-value pairs) ── */ .admin-dl { font-size: 0.875rem; } .admin-dl-row { display: flex; gap: 0.5rem; padding-block: 0.25rem; } .admin-dl-term { width: 7rem; flex-shrink: 0; color: var(--admin-text-muted); } .admin-dl-value { color: var(--t-text-primary); } /* ── Tab navigation ── */ .admin-tabs { display: flex; gap: 0.5rem; margin-top: 1.5rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--t-surface-sunken); } .admin-tab { padding: 0.5rem 0.75rem; font-size: 0.875rem; font-weight: 500; border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--admin-text-muted); &:hover { color: var(--t-text-primary); border-bottom-color: var(--t-border-default); } } .admin-tab-active { color: var(--t-text-primary); border-bottom-color: var(--t-text-primary); } .admin-tab-count { margin-inline-start: 0.25rem; font-size: 0.75rem; color: var(--admin-text-faintest); } /* ── Status dot indicators (inline status with coloured dot) ── */ .admin-status-dot { display: inline-flex; align-items: center; gap: 0.25rem; font-size: 0.875rem; } .admin-status-dot::before { content: ""; width: 0.375rem; height: 0.375rem; border-radius: 9999px; background: var(--_dot-color, var(--t-border-default)); } .admin-status-dot-green { --_dot-color: #22c55e; color: #15803d; } .admin-status-dot-amber { --_dot-color: #f59e0b; color: #b45309; } .admin-status-dot-blue { --_dot-color: #3b82f6; color: #1d4ed8; } .admin-status-dot-red { --_dot-color: #ef4444; color: #b91c1c; } .admin-status-dot-muted { --_dot-color: var(--t-border-default); color: var(--admin-text-muted); } /* ── Stat cards (number + label) ── */ .admin-stat-card { padding: 1rem; border-radius: 0.5rem; border: 1px solid var(--t-surface-sunken); text-align: center; } .admin-stat-value { font-size: 1.5rem; font-weight: 700; } .admin-stat-label { font-size: 0.875rem; color: var(--admin-text-muted); } /* ── Info box (warning/notice with ring) ── */ .admin-info-box { border-radius: 0.375rem; padding: 1rem; font-size: 0.875rem; } .admin-info-box-amber { background: #fffbeb; color: #92400e; box-shadow: inset 0 0 0 1px rgb(217 119 6 / 0.1); } .admin-info-box-amber pre { margin-top: 0.5rem; border-radius: 0.25rem; background: #fef3c7; padding: 0.5rem; font-size: 0.75rem; color: #78350f; overflow-x: auto; } .admin-info-box .admin-btn-primary { color: var(--t-text-inverse); } /* ── TOTP / 2FA ── */ .admin-totp-setup { display: flex; flex-direction: column; gap: 1.25rem; align-items: center; text-align: center; } .admin-totp-qr { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; } .admin-qr-code { padding: 1rem; background: white; border-radius: 0.5rem; box-shadow: 0 1px 3px rgb(0 0 0 / 0.1); } .admin-qr-code svg { display: block; width: 180px; height: 180px; } .admin-totp-divider { display: flex; align-items: center; gap: 0.75rem; width: 100%; color: var(--admin-text-muted); font-size: 0.8125rem; &::before, &::after { content: ""; flex: 1; height: 1px; background: var(--admin-border); } } .admin-totp-copy { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; width: 100%; } .admin-copy-field { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem; background: var(--admin-bg-secondary); border-radius: 0.375rem; max-width: 100%; } .admin-copy-field code { font-size: 0.8125rem; word-break: break-all; } .admin-backup-codes { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; margin-top: 1rem; } .admin-backup-code { padding: 0.375rem 0.75rem; background: white; border-radius: 0.25rem; font-family: ui-monospace, monospace; font-size: 0.875rem; text-align: center; letter-spacing: 0.05em; } .admin-dl-compact { font-size: 0.8125rem; } .admin-dl-compact .admin-dl-row { padding-block: 0.25rem; } /* ── Link variants ── */ .admin-link-danger { font-size: 0.875rem; color: #dc2626; &:hover { color: #991b1b; } } .admin-link-subtle { font-size: 0.875rem; color: var(--admin-text-muted); &:hover { color: var(--t-text-primary); } } /* ── Toggle switch ── */ .admin-switch { display: inline-flex; align-items: center; flex-shrink: 0; cursor: pointer; border-radius: 9999px; transition: background-color 0.15s; width: 2.75rem; height: 1.5rem; padding: 0.125rem; } .admin-switch-on { background: #16a34a; } .admin-switch-off { background: var(--t-border-default); } .admin-switch-thumb { pointer-events: none; display: inline-block; width: 1.25rem; height: 1.25rem; border-radius: 9999px; background: white; box-shadow: 0 1px 2px rgb(0 0 0 / 0.1); transition: transform 0.15s; } .admin-switch-thumb-on { transform: translateX(1.25rem); } /* ── App layout (auth/setup pages) ── */ .app-main { padding: 3rem 1rem; } @media (min-width: 640px) { .app-main { padding: 3rem 1.5rem; } } @media (min-width: 1024px) { .app-main { padding: 3rem 2rem; } } .app-container { max-width: 32rem; margin-inline: auto; display: flex; flex-direction: column; gap: 1rem; } /* ── Theme toggle ── */ .theme-toggle { position: relative; display: flex; flex-direction: row; align-items: center; border: 2px solid var(--t-border-default); background: var(--t-border-default); border-radius: 9999px; } .theme-toggle-indicator { position: absolute; width: 33.333%; height: 100%; border-radius: 9999px; background: var(--t-surface-raised, #fff); left: 0; transition: left 200ms ease; } .theme-toggle-btn { display: flex; padding: 0.5rem; cursor: pointer; width: 33.333%; z-index: 1; opacity: 0.6; &[aria-pressed="true"] { opacity: 1; } } /* ── Setup page ── */ .setup-page { max-width: 36rem; margin: 0 auto; padding: 2rem 1rem; display: flex; flex-direction: column; gap: 1rem; } .setup-header { text-align: center; margin-bottom: 1rem; } .setup-footer { text-align: center; font-size: 0.8125rem; color: var(--admin-text-muted); } .setup-hint { font-size: 0.75rem; color: var(--admin-text-muted); margin-top: -0.5rem; } .setup-title { font-size: 1.5rem; font-weight: 700; line-height: 1.2; } .setup-subtitle { color: var(--admin-text-muted); margin-top: 0.25rem; font-size: 0.875rem; } .setup-sections { display: flex; flex-direction: column; gap: 1rem; } .setup-card { border: 1px solid var(--t-border-default, #d4d4d4); border-radius: 0.5rem; padding: 1.25rem; transition: border-color 150ms; } .setup-card-done { border-color: var(--t-status-success, #22c55e); background: color-mix(in oklab, var(--t-status-success, #22c55e) 5%, transparent); } .setup-card-header { display: flex; align-items: center; gap: 0.75rem; } .setup-card-number { display: flex; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem; border-radius: 50%; font-size: 0.75rem; font-weight: 600; flex-shrink: 0; background: var(--t-surface-sunken, #e5e5e5); color: var(--admin-text-muted); } .setup-card-number-done { background: var(--t-status-success, #22c55e); color: white; } .setup-card-title { font-size: 0.9375rem; font-weight: 600; } .setup-card-summary { margin-top: 0.25rem; padding-inline-start: 2.5rem; font-size: 0.8125rem; color: var(--admin-text-muted); } .setup-card-body { margin-top: 1rem; padding-inline-start: 2.5rem; } .setup-hint { font-size: 0.8125rem; color: var(--admin-text-muted); margin-bottom: 0.75rem; } .setup-field-note { font-size: 0.75rem; color: var(--admin-text-muted); margin-top: -0.5rem; margin-bottom: 0.75rem; } .setup-link { color: var(--t-text-primary, #171717); text-decoration: underline; } .setup-key-hint { font-size: 0.75rem; color: var(--admin-text-muted); margin-top: 0.25rem; } .setup-actions { display: flex; gap: 0.5rem; margin-top: 0.75rem; } .setup-test-result { margin-top: 0.5rem; font-size: 0.8125rem; } .setup-test-ok { color: var(--t-status-success, #22c55e); display: flex; align-items: center; gap: 0.25rem; } .setup-test-error { color: var(--t-status-error, #dc2626); display: flex; align-items: center; gap: 0.25rem; } .setup-test-help { margin: 0.375rem 0 0; font-size: 0.8125rem; } /* Card radio group — selectable cards backed by radio inputs */ .card-radio-fieldset { border: none; padding: 0; margin: 0; } .card-radio-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; margin-top: 0.5rem; @media (max-width: 30rem) { grid-template-columns: 1fr; } } .card-radio-card { display: flex; flex-direction: column; align-items: flex-start; gap: 0.125rem; padding: 0.75rem; border: 1px solid var(--t-border-default, #d4d4d4); border-radius: 0.375rem; cursor: pointer; transition: border-color 150ms, background 150ms; -webkit-tap-highlight-color: transparent; @media (hover: hover) { &:hover:not(:has(:disabled)) { border-color: var(--admin-text-faintest); } } &:active:not(:has(:disabled)) { background: color-mix(in oklch, var(--t-surface-sunken) 50%, transparent); } &:has(:focus-visible) { outline: 2px solid var(--t-accent, oklch(0.55 0.2 250)); outline-offset: 2px; } &:has(:checked) { border-color: var(--t-text-primary, #171717); background: var(--t-surface-sunken, #e5e5e5); } } .card-radio-card-disabled { opacity: 0.5; cursor: not-allowed; } .card-radio-input { position: absolute; opacity: 0; pointer-events: none; } .card-radio-name { display: flex; align-items: baseline; gap: 0.25rem; font-size: 0.875rem; font-weight: 600; } .card-radio-description { font-size: 0.75rem; color: var(--admin-text-muted); } .card-radio-badge { font-size: 0.6875rem; padding: 0.125rem 0.375rem; border-radius: 9999px; background: var(--t-surface-sunken, #e5e5e5); color: var(--admin-text-muted); } .card-radio-link { font-size: 0.6875rem; color: var(--admin-text-muted); text-decoration: underline; text-underline-offset: 2px; &:hover { color: var(--t-text-primary, #171717); } } /* Tags display mode */ .card-radio-tags { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-top: 0.125rem; } .card-radio-tag { font-size: 0.625rem; padding: 0.0625rem 0.375rem; border-radius: 9999px; background: var(--t-surface-sunken, #e5e5e5); color: var(--admin-text-soft); white-space: nowrap; } .setup-provider-form { margin-top: 0.75rem; } /* Setup complete card */ .setup-complete { text-align: center; margin-top: 2rem; padding: 2rem; border: 1px solid var(--t-status-success, #22c55e); border-radius: 0.5rem; background: color-mix(in oklab, var(--t-status-success, #22c55e) 5%, transparent); } .setup-complete-icon { width: 3rem; height: 3rem; color: var(--t-status-success, #22c55e); margin: 0 auto 0.75rem; } .setup-complete h2 { font-size: 1.125rem; font-weight: 600; } .setup-complete p { font-size: 0.875rem; color: var(--admin-text-muted); margin: 0.25rem 0 1rem; } /* ── Guided setup flow ── */ .setup-guided { max-width: 600px; margin: 0 auto; } /* Progress bar */ .setup-progress { margin-bottom: 2rem; } .setup-progress-list { display: flex; justify-content: center; gap: 0.5rem; list-style: none; padding: 0; margin: 0; } .setup-progress-item { flex: 1; max-width: 140px; } .setup-progress-button { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; width: 100%; padding: 0.5rem; border: none; background: none; cursor: pointer; font: inherit; color: var(--admin-text-muted); transition: color 0.15s; } .setup-progress-button:hover:not(:disabled) { color: var(--t-text-primary, #171717); } .setup-progress-button:disabled { cursor: default; } .setup-progress-indicator { display: flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; border-radius: 50%; border: 2px solid var(--t-border-default, #d4d4d4); background: var(--t-surface-base, #fff); font-size: 0.875rem; font-weight: 600; transition: all 0.15s; } .setup-progress-done .setup-progress-indicator { background: var(--t-status-success, #22c55e); border-color: var(--t-status-success, #22c55e); color: #fff; } .setup-progress-current .setup-progress-indicator { border-color: var(--t-accent, #6366f1); color: var(--t-accent, #6366f1); } .setup-progress-label { font-size: 0.75rem; font-weight: 500; } .setup-progress-current .setup-progress-label { color: var(--t-text-primary, #171717); font-weight: 600; } /* Intro screen */ .setup-intro { text-align: center; padding: 1.5rem; border: 1px solid var(--t-border-default, #d4d4d4); border-radius: 0.75rem; background: var(--t-surface-base, #fff); } .setup-intro-content { text-align: left; max-width: 480px; margin: 0 auto; } .setup-intro-lead { font-size: 1rem; line-height: 1.6; margin-bottom: 1.5rem; } .setup-intro-list { list-style: none; padding: 0; margin: 0 0 1.5rem; display: flex; flex-direction: column; gap: 1rem; } .setup-intro-list li { display: flex; align-items: flex-start; gap: 0.75rem; } .setup-intro-icon { width: 1.25rem; height: 1.25rem; color: var(--t-accent, #6366f1); flex-shrink: 0; margin-top: 0.125rem; } .setup-intro-list strong { display: block; font-weight: 600; margin-bottom: 0.125rem; } .setup-intro-list span { font-size: 0.875rem; color: var(--admin-text-muted); } .setup-intro-note { font-size: 0.875rem; color: var(--admin-text-muted); padding: 0.75rem 1rem; background: var(--t-surface-sunken, #f5f5f5); border-radius: 0.5rem; margin-bottom: 1rem; } .setup-actions-center { justify-content: center; } /* Step container */ .setup-step { border: 1px solid var(--t-border-default, #d4d4d4); border-radius: 0.75rem; background: var(--t-surface-base, #fff); overflow: hidden; } .setup-step-header { display: flex; align-items: center; gap: 0.75rem; padding: 1rem 1.25rem; border-bottom: 1px solid var(--t-border-default, #d4d4d4); background: var(--t-surface-sunken, #f5f5f5); } .setup-step-number { display: flex; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem; border-radius: 50%; background: var(--t-accent, #6366f1); color: #fff; font-size: 0.875rem; font-weight: 600; } .setup-step-number-done { background: var(--t-status-success, #22c55e); } .setup-step-title { font-size: 1rem; font-weight: 600; margin: 0; } .setup-step-body { padding: 1.25rem; } .setup-step-done { display: flex; align-items: center; gap: 0.5rem; padding: 0.75rem 1rem; background: color-mix(in oklab, var(--t-status-success, #22c55e) 10%, transparent); border-radius: 0.5rem; margin-bottom: 1rem; } .setup-step-done-icon { width: 1.25rem; height: 1.25rem; color: var(--t-status-success, #22c55e); } .setup-step-done p { margin: 0; font-size: 0.875rem; } /* Step navigation */ .setup-step-nav { display: flex; justify-content: space-between; align-items: flex-start; padding: 1rem 1.25rem; border-top: 1px solid var(--t-border-default, #d4d4d4); background: var(--t-surface-sunken, #f5f5f5); } .setup-step-nav-left, .setup-step-nav-right { display: flex; align-items: center; } .setup-step-back { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.5rem 0.75rem; border: none; background: none; font: inherit; font-size: 0.875rem; color: var(--admin-text-muted); cursor: pointer; transition: color 0.15s; } .setup-step-back:hover { color: var(--t-text-primary, #171717); } .setup-step-skip { text-align: right; } .setup-step-skip-btn { padding: 0.5rem 1rem; border: 1px solid var(--t-border-default, #d4d4d4); border-radius: 0.375rem; background: var(--t-surface-base, #fff); font: inherit; font-size: 0.875rem; cursor: pointer; transition: all 0.15s; } .setup-step-skip-btn:hover { border-color: var(--t-border-input, #a3a3a3); } .setup-step-skip-note { font-size: 0.75rem; color: var(--admin-text-muted); margin-top: 0.5rem; max-width: 200px; } /* ── Dashboard launch checklist ── */ .admin-checklist { border: 1px solid var(--t-border-default, #d4d4d4); border-radius: 0.5rem; padding: 1.25rem; margin-bottom: 1.5rem; } .admin-checklist-header { display: flex; align-items: center; justify-content: space-between; width: 100%; margin-bottom: 1rem; padding: 0; border: none; background: none; cursor: pointer; font: inherit; color: inherit; text-align: left; } .admin-checklist-title { font-size: 1rem; font-weight: 600; } .admin-checklist-progress { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8125rem; color: var(--admin-text-muted); } .admin-checklist-bar { width: 6rem; height: 0.375rem; border-radius: 9999px; background: var(--t-surface-sunken, #e5e5e5); overflow: hidden; } .admin-checklist-bar-fill { height: 100%; border-radius: 9999px; background: var(--t-status-success, #22c55e); transition: width 300ms; } .admin-checklist-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; } .admin-checklist-item { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.5rem 0; } .admin-checklist-content { flex: 1; min-width: 0; } .admin-checklist-row { display: flex; align-items: center; gap: 0.75rem; } .admin-checklist-hint { margin: 0.25rem 0 0; font-size: 0.75rem; color: var(--admin-text-muted); line-height: 1.4; } .admin-checklist-optional { display: inline-block; margin-left: 0.375rem; padding: 0.0625rem 0.375rem; font-size: 0.6875rem; font-weight: 500; border-radius: 9999px; background: var(--t-surface-sunken, #e5e5e5); color: var(--admin-text-muted); vertical-align: middle; } .admin-checklist-check { display: flex; align-items: center; justify-content: center; width: 1.25rem; height: 1.25rem; margin-top: 0.125rem; border-radius: 50%; flex-shrink: 0; border: 1.5px solid var(--t-border-default, #d4d4d4); color: transparent; } .admin-checklist-check-done { background: var(--t-status-success, #22c55e); border-color: var(--t-status-success, #22c55e); color: white; } .admin-checklist-label { font-size: 0.875rem; } .admin-checklist-label-done { color: var(--admin-text-muted); } .admin-checklist-action { flex-shrink: 0; } /* When collapsed, the header has no bottom margin */ .admin-checklist-header:only-child { margin-bottom: 0; } .admin-checklist-help { display: inline-flex; margin-left: 0.25rem; color: var(--admin-text-muted); vertical-align: middle; &:hover { color: var(--t-accent); } } /* ── Status banners ── */ .admin-status-banner { display: flex; align-items: center; gap: 0.5rem; padding: 0.75rem 1rem; border-radius: 0.5rem; font-size: 0.875rem; font-weight: 500; } .admin-status-banner-live { background: oklch(0.95 0.05 145); color: oklch(0.35 0.15 145); } .admin-status-banner-setup { background: oklch(0.95 0.05 250); color: oklch(0.35 0.15 250); } /* ── Page editor ── */ .page-list { display: flex; flex-direction: column; gap: 1.5rem; margin-top: 1.5rem; } .page-group-title { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--admin-text-faint); margin-bottom: 0.5rem; } .page-group-cards { display: flex; flex-direction: column; gap: 1px; border: 1px solid var(--t-border-default); border-radius: 0.5rem; overflow: hidden; } .page-card { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem; background: var(--t-surface-base); text-decoration: none; color: var(--t-text-primary); transition: background 100ms; &:not(:last-child) { border-bottom: 1px solid var(--t-border-default); } @media (hover: hover) { &:hover { background: var(--t-surface-sunken); } } } .page-card-icon { display: flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; border-radius: 0.375rem; background: var(--t-surface-sunken); flex-shrink: 0; color: var(--admin-text-muted); } .page-card-info { flex: 1; display: flex; flex-direction: column; min-width: 0; } .page-card-title { font-size: 0.875rem; font-weight: 500; } .page-card-meta { font-size: 0.75rem; color: var(--admin-text-faint); } .page-card-arrow { flex-shrink: 0; color: var(--admin-text-ghost); } .page-card-custom { padding: 0; display: flex; align-items: stretch; } .page-card-link { flex: 1; display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 0 0.75rem 1rem; text-decoration: none; color: var(--t-text-primary); min-width: 0; @media (hover: hover) { &:hover { background: var(--t-surface-sunken); } } } .page-card-action { display: flex; align-items: center; padding: 0 0.25rem; color: var(--admin-text-ghost); cursor: pointer; border: none; background: none; @media (hover: hover) { &:hover { color: var(--t-text-primary); } } } .page-card-delete { display: flex; align-items: center; padding: 0 0.75rem 0 0.25rem; color: var(--admin-text-ghost); cursor: pointer; border: none; background: none; @media (hover: hover) { &:hover { color: var(--t-error); } } } /* ── Template picker ── */ .template-picker { margin-top: 1.5rem; max-width: 32rem; } .template-picker-label { font-size: 0.875rem; font-weight: 500; margin-bottom: 0.5rem; color: var(--t-text-primary); } .template-picker-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; } .template-card { display: flex; flex-direction: column; gap: 0.25rem; padding: 0.75rem; border: 1px solid var(--t-border-default); border-radius: var(--t-radius); background: var(--t-surface-base); cursor: pointer; text-align: left; color: var(--t-text-primary); transition: border-color 0.15s; } .template-card:hover { border-color: var(--t-text-secondary); } .template-card-selected { border-color: var(--t-accent-button); background: color-mix(in oklch, var(--t-accent-button) 8%, var(--t-surface-base)); } .template-card-name { font-weight: 600; font-size: 0.875rem; } .template-card-desc { font-size: 0.75rem; color: var(--t-text-secondary); } /* Inline page settings panel */ .page-settings-panel { margin-top: 1rem; padding: 1rem; border: 1px solid var(--t-border-default); border-radius: 0.5rem; background: var(--t-surface-sunken); } .page-settings-fields { display: grid; gap: 0.75rem; @media (min-width: 40em) { grid-template-columns: 1fr 1fr; } } .page-settings-row { display: flex; gap: 1.5rem; align-items: center; } .page-settings-actions { display: flex; gap: 0.5rem; margin-top: 1rem; padding-top: 0.75rem; border-top: 1px solid var(--t-border-default); } /* Page editor split layout */ .page-editor-container { display: flex; flex-direction: column; gap: 1rem; margin-top: 1rem; } .page-editor-pane-hidden-mobile { display: none; } .page-editor-preview-hidden-mobile { display: none; } .page-editor-preview-pane { border: 1px solid color-mix(in oklch, var(--t-text-primary) 15%, transparent); border-radius: 0.5rem; overflow: hidden; } .page-editor-preview { transform: scale(0.55); transform-origin: top left; width: 181.82%; /* 1/0.55 */ pointer-events: none; } .page-editor-toggle-preview { display: inline-flex; } @media (min-width: 64em) { .page-editor-container { flex-direction: row; gap: 1.5rem; } .page-editor-pane { flex: 1; min-width: 0; overflow-y: auto; } .page-editor-pane-hidden-mobile { display: block; } .page-editor-preview-pane { flex: 1; min-width: 0; max-height: calc(100vh - 14rem); overflow-y: auto; position: sticky; top: 1rem; } .page-editor-preview-hidden-mobile { display: block; } .page-editor-toggle-preview { display: none; } } /* Block list in editor */ .block-list { display: flex; flex-direction: column; gap: 0.375rem; margin-top: 0; @media (min-width: 768px) { gap: 0.5rem; } } .block-list-empty { text-align: center; padding: 2rem; color: var(--admin-text-faint); font-size: 0.875rem; border: 1px dashed var(--t-border-default); border-radius: 0.5rem; } .block-card { padding: 0.375rem 0.5rem; border: 1px solid var(--t-border-default); border-radius: 0.375rem; background: var(--t-surface-base); transition: box-shadow 150ms; &:focus-within { box-shadow: 0 0 0 2px color-mix(in oklch, var(--t-text-primary) 20%, transparent); } @media (min-width: 768px) { padding: 0.5rem 0.75rem; border-radius: 0.5rem; } } .block-card-position { display: flex; align-items: center; justify-content: center; width: 1.25rem; height: 1.25rem; border-radius: 0.25rem; font-size: 0.6875rem; font-weight: 600; color: var(--admin-text-faint); flex-shrink: 0; @media (min-width: 768px) { width: 1.5rem; height: 1.5rem; font-size: 0.75rem; } } .block-card-icon { display: none; align-items: center; color: var(--admin-text-muted); flex-shrink: 0; @media (min-width: 768px) { display: flex; } } .block-card-info { flex: 1; min-width: 6rem; } .block-card-name { display: block; font-size: 0.8125rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @media (min-width: 768px) { font-size: 0.875rem; } } .block-card-preview { display: none; font-size: 0.75rem; color: var(--admin-text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @media (min-width: 768px) { display: block; } } .block-card-controls { display: flex; align-items: center; gap: 0.125rem; flex-shrink: 0; margin-left: auto; } .block-remove-btn { color: color-mix(in oklch, var(--t-status-error) 70%, transparent); @media (hover: hover) { &:hover { color: var(--t-status-error); } } } /* Add block button */ .block-actions { margin-top: 1rem; display: flex; justify-content: center; } .block-add-btn { border-style: dashed; } /* Block picker */ .block-picker-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.3); z-index: 50; display: flex; align-items: flex-end; justify-content: center; @media (min-width: 40em) { align-items: center; } } .block-picker { background: var(--t-surface-base); border-radius: 0.75rem 0.75rem 0 0; width: 100%; max-height: 80vh; overflow-y: auto; padding: 1rem; @media (min-width: 40em) { border-radius: 0.75rem; max-width: 36rem; } } .block-picker-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.75rem; & h3 { font-size: 1rem; font-weight: 600; } } .block-picker-search { width: 100%; margin-bottom: 0.75rem; } .block-picker-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; } .block-picker-item { display: grid; grid-template-columns: 1.25rem 1fr; gap: 0.25rem 0.5rem; align-items: start; padding: 0.625rem 0.75rem; border: 1px solid var(--t-border-default); border-radius: 0.375rem; background: none; font-size: 0.8125rem; cursor: pointer; text-align: left; color: inherit; transition: background 100ms; @media (hover: hover) { &:hover { background: var(--t-surface-sunken); } } } .block-picker-thumb { grid-column: 1 / -1; width: 100%; height: auto; border-radius: 0.25rem; background: color-mix(in oklch, var(--t-text-primary) 3%, transparent); margin-bottom: 0.25rem; } .block-picker-item > .size-5 { margin-top: 0.0625rem; } .block-picker-item-name { grid-column: 2; } .block-picker-item-desc { grid-column: 1 / -1; font-size: 0.6875rem; line-height: 1.3; color: color-mix(in oklch, var(--t-text-primary) 55%, transparent); } .block-picker-empty { grid-column: 1 / -1; text-align: center; padding: 1rem; color: var(--admin-text-faint); font-size: 0.8125rem; } /* Block card header + expanded state */ .block-card-header { display: flex; align-items: center; gap: 0.25rem 0.5rem; flex-wrap: wrap; width: 100%; /* Desktop: single row with truncating text */ @media (min-width: 768px) { flex-wrap: nowrap; } } .block-card-expanded { background: var(--t-surface-sunken); } .block-edit-btn-active { color: var(--t-accent); } /* Block settings panel */ .block-settings-hint { display: flex; align-items: flex-start; gap: 0.375rem; font-size: 0.75rem; color: var(--admin-text-muted); background: color-mix(in oklch, var(--t-accent) 8%, transparent); border: 1px solid color-mix(in oklch, var(--t-accent) 20%, transparent); border-radius: 0.375rem; padding: 0.5rem 0.625rem; margin-bottom: 0.5rem; line-height: 1.4; } .block-settings-hint svg { flex-shrink: 0; color: var(--t-accent); margin-top: 0.05rem; } .block-card-settings { padding: 0.75rem 0.75rem 0.25rem; padding-left: 2.75rem; border-top: 1px solid var(--t-border-default); animation: blockSettingsFadeIn 0.15s ease; } @keyframes blockSettingsFadeIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } } .block-settings-fields { display: flex; flex-direction: column; gap: 0.625rem; } /* Repeater fields */ .repeater-field { display: flex; flex-direction: column; gap: 0.5rem; } .repeater-items { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.5rem; } .repeater-item { border: 1px solid var(--t-border-default); border-radius: 0.375rem; padding: 0.5rem; & fieldset { border: none; padding: 0; margin: 0; } } .repeater-item-fields { display: flex; flex-direction: column; gap: 0.375rem; } .repeater-item-controls { display: flex; gap: 0.125rem; justify-content: flex-end; margin-top: 0.375rem; } .repeater-remove-btn { color: var(--t-danger); } .repeater-add-btn { align-self: flex-start; border-style: dashed; } /* ══════════════════════════════════════════════════════════════════════════ Editor FAB + Panel (page editing) Two separate elements: - .editor-fab: floating action button, always a pill in the corner - .editor-panel: sliding panel, animates in/out ══════════════════════════════════════════════════════════════════════════ */ /* ── Floating action button ── */ .editor-fab { position: fixed; z-index: 1000; right: 16px; bottom: 16px; display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.875rem; background: oklch(0.5 0.18 280); color: #fff; border: none; border-radius: 9999px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: filter 0.15s, box-shadow 0.15s; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2), 0 0 0 3px rgba(255, 255, 255, 0.6); } .editor-fab:hover { filter: brightness(1.1); } .editor-fab svg { width: 16px; height: 16px; flex-shrink: 0; } .editor-fab-dirty { width: 8px; height: 8px; border-radius: 9999px; background: var(--t-status-warning, oklch(0.75 0.18 85)); flex-shrink: 0; } /* ── Editor overlay ── */ .editor-overlay { position: fixed; inset: 0; z-index: 999; background: transparent; cursor: pointer; } /* On larger screens, hide the overlay so you can navigate while editing */ @media (min-width: 768px) { .editor-overlay { display: none; } } /* ── Editor panel ── */ .editor-panel { position: fixed; z-index: 1000; display: flex; flex-direction: column; background: var(--t-surface-base); box-shadow: var(--t-shadow-lg, 0 8px 24px rgba(0, 0, 0, 0.15)); /* Force GPU compositing to prevent paint flickering during drag */ transform: translateZ(0); backface-visibility: hidden; isolation: isolate; } /* Hidden when collapsed (but not during close animation) */ .editor-panel[data-state="collapsed"]:not(.closing) { display: none; } /* ── Drag handle (mobile only) ── */ .editor-panel-drag-handle { display: none; } @media (max-width: 767px) { .editor-panel-drag-handle { display: flex; justify-content: center; align-items: center; padding: 0.5rem; cursor: grab; touch-action: none; flex-shrink: 0; } .editor-panel-drag-handle:active { cursor: grabbing; } .editor-panel-drag-handle-bar { width: 2.5rem; height: 4px; border-radius: 2px; background: var(--t-border-default); } } /* ── Mobile: bottom sheet ── */ @media (max-width: 767px) { .editor-panel[data-state="open"], .editor-panel.closing { left: 0; right: 0; bottom: 0; /* Default 50vh, overridden by JS with saved preference */ height: var(--editor-panel-height, 50dvh); max-height: 90dvh; min-height: 200px; border-radius: var(--t-radius-lg, 12px) var(--t-radius-lg, 12px) 0 0; border: 1px solid var(--t-border-default); border-bottom: none; /* Keep layer promoted to prevent flash on resize end */ will-change: transform; contain: strict; } /* During drag: disable animations and also hint height changes */ .editor-panel.dragging { transition: none !important; will-change: transform, height; } /* Only animate on initial open, not after drag ends */ .editor-panel[data-state="open"]:not(.dragging):not(.has-dragged) { animation: editor-panel-slide-up 0.3s cubic-bezier(0.32, 0.72, 0, 1) both; } .editor-panel.closing { animation: editor-panel-slide-down 0.25s cubic-bezier(0.32, 0.72, 0, 1) both; } } @keyframes editor-panel-slide-up { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } } @keyframes editor-panel-slide-down { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(24px); } } /* ── Desktop: side panel ── */ @media (min-width: 768px) { .editor-panel[data-state="open"], .editor-panel.closing { top: 0; right: 0; bottom: 0; width: 420px; max-width: 90vw; border-radius: var(--t-radius-lg, 12px) 0 0 var(--t-radius-lg, 12px); border: 1px solid var(--t-border-default); border-right: none; } .editor-panel[data-state="open"] { animation: editor-panel-slide-in 0.3s cubic-bezier(0.32, 0.72, 0, 1) both; } .editor-panel.closing { animation: editor-panel-slide-out 0.25s cubic-bezier(0.32, 0.72, 0, 1) both; } } @keyframes editor-panel-slide-in { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: translateX(0); } } @keyframes editor-panel-slide-out { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(24px); } } /* Disable animations for users who prefer reduced motion */ @media (prefers-reduced-motion: reduce) { .editor-panel[data-state="open"], .editor-panel.closing { animation: none; } } /* ── Panel header ── */ .editor-panel-header { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1rem; border-bottom: 1px solid var(--t-border-default); flex-shrink: 0; gap: 0.5rem; } .editor-panel-header-left { display: flex; align-items: center; gap: 0.75rem; min-width: 0; } .editor-panel-title { font-size: 0.875rem; font-weight: 600; color: var(--t-text-primary); } .editor-panel-header-actions { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; } .editor-panel-close { display: flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; padding: 0; border: none; border-radius: 0.375rem; background: transparent; color: var(--t-text-secondary); cursor: pointer; transition: background-color 0.15s, color 0.15s; &:hover { background: var(--t-border-default); color: var(--t-text-primary); } } /* ── Dirty indicator ── */ .editor-panel-dirty { display: flex; align-items: center; gap: 0.25rem; color: var(--t-status-warning, oklch(0.75 0.18 85)); font-size: 0.75rem; font-weight: 500; } .editor-panel-dirty-dot { width: 8px; height: 8px; border-radius: 9999px; background: currentColor; } /* ── Tab bar ── */ .editor-tabs { display: flex; gap: 0; border-bottom: 1px solid var(--t-border-default); padding: 0 0.75rem; flex-shrink: 0; } .editor-tab { flex: 1; padding: 0.5rem 0.75rem; font-size: 0.8125rem; font-weight: 500; color: var(--t-text-secondary); background: none; border: none; border-bottom: 2px solid transparent; cursor: pointer; transition: color 0.15s, border-color 0.15s; &:hover:not(:disabled) { color: var(--t-text-primary); } &:disabled { opacity: 0.4; cursor: not-allowed; } } .editor-tab-active { color: var(--t-text-primary); border-bottom-color: var(--t-accent, oklch(0.6 0.15 250)); } /* ── Panel content ── */ .editor-panel-content { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 0.75rem; /* Ensure content is clipped to panel bounds during drag */ contain: paint; @media (min-width: 768px) { padding: 1rem; } } /* ── Page header inside panel ── */ .editor-panel-page-header { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.5rem; @media (min-width: 768px) { margin-bottom: 0.75rem; } } .editor-panel-page-title { font-size: 0.9375rem; font-weight: 600; flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @media (min-width: 768px) { font-size: 1rem; } } .editor-panel-undo-redo { display: flex; align-items: center; gap: 0.25rem; flex-shrink: 0; } /* Picker inside the editor panel — grid scrolls within a capped height */ .editor-panel .block-picker-overlay { position: static; background: none; } .editor-panel .block-picker { border-radius: 0; max-height: none; padding: 0; } .editor-panel .block-picker-grid { max-height: 45dvh; overflow-y: auto; } /* ═══════════════════════════════════════════════════════════════════ Image field (block editor) ═══════════════════════════════════════════════════════════════════ */ .image-field { display: flex; flex-direction: column; gap: 0.5rem; } .image-field-preview { display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem; border: 1px solid var(--t-surface-sunken); border-radius: 0.375rem; background: var(--t-surface-base); } .image-field-thumb { width: 48px; height: 48px; object-fit: cover; border-radius: 0.25rem; flex-shrink: 0; } .image-field-svg { width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; background: var(--t-surface-sunken); border-radius: 0.25rem; flex-shrink: 0; color: var(--t-text-primary); opacity: 0.5; } .image-field-info { display: flex; flex-direction: column; min-width: 0; } .image-field-filename { font-size: 0.8125rem; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .image-field-alt { font-size: 0.75rem; color: var(--t-text-primary); opacity: 0.6; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .image-field-actions { display: flex; gap: 0.375rem; } .image-field-remove-btn { color: var(--t-accent); } .image-field-choose-btn { width: 100%; justify-content: center; } /* ── Image picker modal ─────────────────────────────────────────── */ .image-picker-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.3); z-index: 50; display: flex; align-items: flex-end; justify-content: center; @media (min-width: 40em) { align-items: center; } } .image-picker { background: var(--t-surface-base); border-radius: 0.75rem 0.75rem 0 0; width: 100%; max-height: 80vh; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; @media (min-width: 40em) { border-radius: 0.75rem; max-width: 32rem; } } .image-picker-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.75rem; & h3 { font-size: 1rem; font-weight: 600; } } .image-picker-search { width: 100%; margin-bottom: 0.75rem; } .image-picker-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; overflow-y: auto; @media (min-width: 40em) { grid-template-columns: repeat(3, 1fr); } } .image-picker-item { position: relative; display: flex; flex-direction: column; align-items: center; gap: 0.375rem; padding: 0.375rem; border: 1px solid var(--t-border-default); border-radius: 0.375rem; background: none; cursor: pointer; text-align: center; color: inherit; transition: background 100ms; overflow: clip; min-width: 0; @media (hover: hover) { &:hover { background: var(--t-surface-sunken); } } } .image-picker-item-thumb, .image-picker-item-svg { width: 100%; aspect-ratio: 1; border-radius: 0.25rem; background: var(--t-surface-sunken); } .image-picker-item-thumb { object-fit: cover; } .image-picker-item-svg { display: flex; align-items: center; justify-content: center; color: var(--t-text-primary); opacity: 0.5; } .image-picker-item-name { font-size: 0.6875rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; } .image-picker-empty { grid-column: 1 / -1; text-align: center; padding: 1.5rem; color: var(--admin-text-faint); font-size: 0.8125rem; } .image-picker-upload { margin-bottom: 0.75rem; } .image-picker-upload-label { display: flex; align-items: center; justify-content: center; gap: 0.5rem; padding: 0.5rem; border: 1px dashed var(--t-border-default); border-radius: 0.375rem; font-size: 0.8125rem; cursor: pointer; color: var(--admin-text-muted); transition: border-color 100ms, color 100ms; @media (hover: hover) { &:hover { border-color: var(--t-text-primary); color: var(--t-text-primary); } } } .image-picker-item-no-alt { color: var(--t-warning, #f59e0b); position: absolute; top: 0.25rem; right: 0.25rem; } /* ═══════════════════════════════════════════════════════════════════ Media library ═══════════════════════════════════════════════════════════════════ */ .media-layout { display: flex; flex-direction: column; gap: 1rem; margin-top: 1rem; } .media-upload-zone { border: 2px dashed var(--t-border-default); border-radius: 0.5rem; padding: 1rem; transition: border-color 0.2s; } .media-upload-zone[phx-drop-active] { border-color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 5%, transparent); } .media-upload-form { display: flex; flex-direction: column; gap: 0.5rem; } .media-upload-row { display: flex; gap: 0.5rem; align-items: center; } .media-upload-progress { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; margin-top: 0.5rem; } .media-upload-progress progress { flex: 1; height: 0.5rem; } .media-main { display: flex; gap: 1rem; min-height: 400px; } .media-grid-wrapper { flex: 1; min-width: 0; } .media-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 0.75rem; align-content: start; } .media-card { border: 2px solid var(--t-surface-sunken); border-radius: 0.5rem; overflow: hidden; cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s; background: var(--t-surface-base); } .media-card:hover { border-color: var(--t-border-default); } .media-card-selected { border-color: var(--color-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 25%, transparent); } .media-card-thumb { aspect-ratio: 1; overflow: hidden; background: var(--t-surface-sunken); display: flex; align-items: center; justify-content: center; } .media-card-thumb img { width: 100%; height: 100%; object-fit: cover; } .media-card-svg-placeholder { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; color: var(--t-text-primary); opacity: 0.5; font-size: 0.75rem; } .media-card-info { padding: 0.5rem; display: flex; flex-direction: column; gap: 0.25rem; } .media-card-filename { font-size: 0.75rem; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .media-card-meta { display: flex; align-items: center; gap: 0.25rem; color: var(--t-text-primary); opacity: 0.7; } .media-card-size { font-size: 0.75rem; } .media-card-no-alt { display: flex; align-items: center; gap: 0.25rem; font-size: 0.625rem; color: var(--color-warning); } /* Detail panel */ .media-detail { width: 320px; min-width: 320px; border: 1px solid var(--t-surface-sunken); border-radius: 0.5rem; background: var(--t-surface-base); padding: 1rem; display: flex; flex-direction: column; gap: 1rem; max-height: calc(100vh - 12rem); overflow-y: auto; position: sticky; top: 5rem; } .media-detail-header { display: flex; justify-content: space-between; align-items: center; } .media-detail-header h3 { font-size: 1rem; font-weight: 600; margin: 0; } .media-detail-preview { aspect-ratio: 16/9; overflow: hidden; border-radius: 0.375rem; background: var(--t-surface-sunken); display: flex; align-items: center; justify-content: center; } .media-detail-preview img { width: 100%; height: 100%; object-fit: contain; } .media-detail-svg { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; color: var(--t-text-primary); opacity: 0.5; } .media-detail-meta { display: grid; grid-template-columns: auto 1fr; gap: 0.25rem 0.75rem; font-size: 0.8125rem; } .media-detail-meta dt { font-weight: 500; color: var(--t-text-primary); opacity: 0.7; } .media-detail-meta dd { margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .media-detail-form { display: flex; flex-direction: column; gap: 0.75rem; } .media-detail-usages { border-top: 1px solid var(--t-surface-sunken); padding-top: 0.75rem; } .media-detail-usages h4 { font-size: 0.875rem; font-weight: 600; margin: 0 0 0.5rem; } .media-detail-usages ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.8125rem; } .media-detail-usages li { display: flex; align-items: center; gap: 0.5rem; } .media-detail-actions { border-top: 1px solid var(--t-surface-sunken); padding-top: 0.75rem; } .media-detail-scrim { display: none; } @media (max-width: 47.99em) { .media-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); } .media-detail-scrim { display: block; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); z-index: 39; animation: media-scrim-fade 0.2s ease-out; } .media-detail { position: fixed; top: auto; bottom: 0; left: 0; right: 0; width: 100%; min-width: unset; max-height: 70vh; border-radius: 0.75rem 0.75rem 0 0; box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.25); z-index: 40; animation: media-sheet-up 0.25s ease-out; padding: 0.75rem 1rem; gap: 0.5rem; } .media-detail-preview { display: none; } .media-detail-meta { font-size: 0.75rem; gap: 0.125rem 0.5rem; } .media-detail-form { gap: 0.25rem; } .media-detail-form .admin-fieldset { margin-bottom: 0; } .media-detail-form .admin-label { font-size: 0.75rem; } } @keyframes media-sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } } @keyframes media-scrim-fade { from { opacity: 0; } to { opacity: 1; } } /* Navigation editor */ .nav-editor-labels { display: flex; gap: 0.5rem; padding: 0 0.5rem; font-size: 0.75rem; font-weight: 500; color: color-mix(in oklch, var(--t-text-primary) 55%, transparent); & span { flex: 1; min-width: 0; } } .nav-editor-item { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem; border: 1px solid var(--t-border-default); border-radius: 0.375rem; background: var(--t-surface-base); } .nav-editor-fields { flex: 1; display: flex; gap: 0.5rem; min-width: 0; } .nav-editor-input { flex: 1; min-width: 0; font-size: 0.875rem; padding: 0.375rem 0.5rem; } .nav-editor-actions { display: flex; gap: 0.125rem; flex-shrink: 0; } .nav-editor-dropdown { position: absolute; top: 100%; left: 0; z-index: 10; margin-top: 0.25rem; min-width: 12rem; background: var(--t-surface-base); border: 1px solid var(--t-border-default); border-radius: 0.375rem; box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1); overflow: hidden; } .nav-editor-dropdown-item { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; width: 100%; padding: 0.5rem 0.75rem; font-size: 0.875rem; text-align: left; cursor: pointer; background: none; border: none; color: var(--t-text-primary); @media (hover: hover) { &:hover { background: var(--t-surface-sunken); } } } /* ── Pagination ── */ .admin-pagination { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--t-surface-sunken, var(--color-base-200)); } .admin-pagination-showing { font-size: 0.875rem; color: color-mix(in oklch, var(--t-text-primary) 55%, transparent); white-space: nowrap; } .admin-pagination-buttons { display: flex; align-items: center; gap: 0.25rem; flex-wrap: wrap; } .admin-pagination-ellipsis { padding-inline: 0.25rem; font-size: 0.875rem; color: color-mix(in oklch, var(--t-text-primary) 35%, transparent); } .admin-btn-disabled { opacity: 0.35; pointer-events: none; } @media (max-width: 35.99em) { .admin-pagination { justify-content: center; } .admin-pagination-showing { width: 100%; text-align: center; } } /* -- Timeline -- */ .admin-timeline { list-style: none; padding: 0; margin: 0; position: relative; } .admin-timeline::before { content: ""; position: absolute; left: 0.4375rem; top: 0.75rem; bottom: 0.75rem; width: 1px; background: var(--t-border-default); } .admin-timeline-item { display: flex; gap: 0.75rem; padding: 0.375rem 0; position: relative; } .admin-timeline-dot { width: 0.875rem; height: 0.875rem; border-radius: 9999px; flex-shrink: 0; margin-top: 0.125rem; border: 2px solid var(--t-surface-base); position: relative; z-index: 1; } .admin-timeline-dot-info { background: var(--t-status-success, #22c55e); } .admin-timeline-dot-warning { background: var(--t-status-warning, #f59e0b); } .admin-timeline-dot-error { background: var(--t-status-error, #ef4444); } .admin-timeline-content { flex: 1; min-width: 0; } .admin-timeline-message { font-size: 0.875rem; line-height: 1.4; margin: 0; } .admin-timeline-time { font-size: 0.75rem; color: var(--admin-text-faint); } /* ── Product thumbnail ── */ .admin-thumbnail { width: 2.5rem; height: 2.5rem; border-radius: 0.25rem; background-color: var(--t-surface-sunken); overflow: hidden; flex-shrink: 0; } .admin-thumbnail img { width: 100%; height: 100%; object-fit: cover; } .admin-thumbnail-placeholder { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; } /* ── Provider badge (small metadata pill) ── */ .admin-provider-badge { display: inline-flex; align-items: center; border-radius: 9999px; background-color: var(--t-surface-sunken); padding: 0.125rem 0.375rem; font-size: 0.75rem; color: var(--admin-text-muted); margin-top: 0.125rem; } /* ── Sale tag ── */ .admin-sale-tag { color: #dc2626; font-size: 0.75rem; font-weight: 500; margin-inline-end: 0.25rem; } /* ── Product show layout ── */ .admin-product-grid { display: grid; gap: 1.5rem; margin-top: 1.5rem; @media (min-width: 1024px) { grid-template-columns: 2fr 1fr; } } .admin-product-image-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; @media (min-width: 640px) { grid-template-columns: repeat(4, 1fr); } } .admin-product-image-tile { aspect-ratio: 1; border-radius: 0.25rem; background-color: var(--t-surface-sunken); overflow: hidden; & img { width: 100%; height: 100%; object-fit: cover; } } /* ── Provider status indicator ── */ .admin-provider-dot { display: inline-flex; width: 0.75rem; height: 0.75rem; border-radius: 9999px; } .admin-provider-dot-idle { background: var(--admin-text-ghost); } .admin-provider-dot-syncing { background: var(--t-status-warning); animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; } .admin-provider-dot-ok { background: var(--t-status-success); } .admin-provider-dot-error { background: var(--t-status-error); } @keyframes pulse { 50% { opacity: 0.5; } } /* ── Nav editor section heading ── */ .admin-nav-section-heading { font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--admin-text-faint); margin-bottom: 0.75rem; } /* -- Activity feed -- */ .admin-activity-row { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.625rem 0; border-bottom: 1px solid color-mix(in oklch, var(--t-border-default) 50%, transparent); } .admin-activity-row:last-child { border-bottom: none; } .admin-activity-icon { flex-shrink: 0; margin-top: 0.125rem; } .admin-activity-icon-error { color: #ef4444; } .admin-activity-icon-warning { color: #f59e0b; } .admin-activity-icon-ok { color: #22c55e; } .admin-activity-body { flex: 1; min-width: 0; font-size: 0.875rem; line-height: 1.4; } .admin-activity-type { font-weight: 500; margin-right: 0.25rem; } .admin-activity-meta { flex-shrink: 0; display: flex; align-items: center; gap: 0.5rem; } .admin-activity-time { font-size: 0.75rem; color: var(--admin-text-faint); white-space: nowrap; } .admin-activity-link { font-size: 0.75rem; line-height: 1rem; color: var(--t-accent); margin-inline-start: 0.25rem; &:hover { text-decoration: underline; } } /* Stream empty state (works with only:block pattern) */ .admin-stream-empty { display: none; text-align: center; padding-block: 2rem; font-size: 0.875rem; line-height: 1.25rem; color: var(--admin-text-muted); } .admin-stream-empty:only-child { display: block; } /* ── Generic admin helpers ── */ /* Main content area with responsive padding */ .admin-main { flex: 1; padding: 1rem; @media (min-width: 40em) { padding: 1.5rem; } @media (min-width: 64em) { padding: 2rem; } } /* Centered max-width content container */ .admin-container { max-width: 64rem; margin-inline: auto; } /* Sidebar footer (dev tools, log out) */ .admin-sidebar-footer { padding: 0.5rem; border-top: 1px solid var(--t-border-default); } .admin-sidebar-email { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.75rem; font-size: 0.75rem; color: var(--t-text-secondary); } /* Dev tools disclosure in sidebar footer */ .admin-dev-tools { & > summary { display: flex; align-items: center; gap: 0.5rem; padding: 0.375rem 0.75rem; font-size: 0.875rem; color: var(--t-text-secondary); cursor: pointer; list-style: none; &::marker, &::-webkit-details-marker { display: none; } } & > summary:hover { color: var(--t-text-primary); } & .admin-dev-tools-chevron { margin-left: auto; transition: transform 0.15s ease; } &[open] .admin-dev-tools-chevron { transform: rotate(90deg); } & > .admin-nav { padding-left: 1rem; } } /* Sidebar nav area */ .admin-sidebar-nav { flex: 1; padding: 0.5rem; } /* Secondary text for user email, help text, meta info */ .admin-text-secondary { font-size: 0.75rem; line-height: 1rem; color: var(--admin-text-muted); } .admin-text-tertiary { font-size: 0.75rem; color: var(--admin-text-faint); } /* Checkbox/toggle + label inline pair */ .admin-check-label { display: flex; align-items: center; gap: 0.75rem; cursor: pointer; } .admin-toggle-label { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; } /* ── Theme editor ── */ .theme-layout { display: flex; flex-direction: column; min-height: 100vh; background: var(--t-surface-sunken); @media (min-width: 48em) { flex-direction: row; height: 100vh; } } .theme-sidebar { background: var(--t-surface-base); border-right: 1px solid var(--t-border-default); flex-shrink: 0; transition: width 0.3s, padding 0.3s; @media (min-width: 48em) { height: 100vh; } } .theme-sidebar-expanded { width: 100%; overflow-y: auto; padding: 1.5rem; @media (min-width: 48em) { width: 380px; } } .theme-sidebar-collapsed { width: 3rem; overflow: hidden; } .theme-sidebar-collapsed-inner { height: 100%; display: flex; align-items: flex-start; justify-content: center; padding-top: 1rem; } .theme-back-link { display: inline-flex; align-items: center; gap: 0.25rem; font-size: 0.875rem; color: var(--admin-text-muted); margin-bottom: 1rem; &:hover { color: var(--t-text-primary); } } .theme-header { margin-bottom: 1.5rem; display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; } .theme-title { font-size: 1.25rem; font-weight: 600; letter-spacing: -0.025em; margin-bottom: 0.5rem; color: var(--t-text-primary); } .theme-subtitle { font-size: 0.875rem; color: var(--admin-text-muted); line-height: 1.6; } /* Collapse/expand toggle button */ .theme-collapse-btn { padding: 0.5rem; border-radius: 0.5rem; transition: background-color 0.1s; flex-shrink: 0; &:hover { background: var(--t-surface-sunken); } } .theme-collapse-icon { width: 1.25rem; height: 1.25rem; color: var(--admin-text-soft); } /* Section label (uppercase heading above option groups) */ .theme-section-label { display: block; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--admin-text-muted); margin-bottom: 0.75rem; } /* Settings panel box with sunken background */ .theme-panel { background: var(--t-surface-sunken); border-radius: 0.75rem; padding: 1rem; margin-bottom: 1.5rem; } /* Field spacing — used for form elements within panels */ .theme-field { margin-bottom: 1rem; } /* Bordered field subsection (logo upload area, etc.) */ .theme-subsection { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--t-border-default); } /* Chip button group */ .theme-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; } /* Individual option chip */ .theme-chip { padding: 0.5rem 0.75rem; font-size: 0.875rem; border-radius: 0.5rem; border: 2px solid transparent; transition: all 0.15s; text-transform: capitalize; background: var(--t-surface-sunken); color: var(--t-text-primary); &:hover { background: var(--t-border-default); } } .theme-chip-active { border-color: var(--t-text-primary); background: var(--t-surface-base); } /* Preset grid (2-column) */ .theme-presets { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; } .theme-preset { padding: 0.75rem; border-radius: 0.5rem; text-align: left; border: 2px solid transparent; transition: all 0.15s; background: var(--t-surface-sunken); color: var(--t-text-primary); &:hover { background: var(--t-border-default); } } .theme-preset-active { border-color: var(--t-text-primary); background: var(--t-surface-base); } .theme-preset-name { font-weight: 600; font-size: 0.875rem; text-transform: capitalize; } .theme-preset-desc { font-size: 0.75rem; color: var(--admin-text-muted); } /* Colour picker inline row */ .theme-color-row { display: flex; align-items: center; gap: 0.75rem; } .theme-color-swatch { width: 3rem; height: 3rem; border-radius: 0.5rem; cursor: pointer; border: 0; padding: 0; } .theme-color-swatch-sm { width: 2.25rem; height: 2.25rem; } .theme-color-value { font-family: monospace; font-size: 0.875rem; color: var(--admin-text-soft); } /* File upload trigger label */ .theme-upload-label { display: block; background: var(--t-surface-base); border: 1px dashed var(--t-border-default); border-radius: 0.5rem; padding: 0.75rem; font-size: 0.875rem; color: var(--admin-text-muted); text-align: center; cursor: pointer; transition: border-color 0.15s, color 0.15s; &:hover { border-color: var(--admin-text-faintest); color: color-mix(in oklch, var(--t-text-primary) 80%, transparent); } } /* Upload progress row */ .theme-progress { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; } .theme-progress-bar { flex: 1; height: 0.375rem; background: var(--t-border-default); border-radius: 9999px; overflow: hidden; } .theme-progress-fill { height: 100%; background: var(--t-accent); transition: width 0.2s; } /* Round remove button (overlaid on thumbnails) */ .theme-remove-btn { position: absolute; top: -0.5rem; inset-inline-end: -0.5rem; width: 1.75rem; height: 1.75rem; background: var(--t-status-error); color: white; border-radius: 9999px; font-size: 1rem; font-weight: 500; display: flex; align-items: center; justify-content: center; line-height: 1; cursor: pointer; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); transition: transform 0.15s ease, background-color 0.15s ease; &:hover { background: color-mix(in oklch, var(--t-status-error) 85%, black); transform: scale(1.1); } } /* Thumbnail preview boxes */ .theme-thumb { position: relative; display: flex; align-items: center; justify-content: center; background: var(--t-surface-base); border: 1px solid var(--t-border-default); border-radius: 0.5rem; } .theme-thumb img { border-radius: 0.375rem; } .theme-thumb-logo { width: 4rem; height: 2.5rem; } .theme-thumb-icon { width: 2.5rem; height: 2.5rem; } .theme-thumb-header { width: 100%; height: 60px; margin-top: 0.5rem; } .theme-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; } .theme-thumb-cover img { width: 100%; height: 100%; object-fit: cover; } /* Slider row (label + value display) */ .theme-slider-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; } .theme-slider-label { font-size: 0.75rem; font-weight: 500; color: var(--admin-text-soft); } .theme-slider-value { font-size: 0.75rem; font-family: monospace; color: var(--admin-text-muted); } /* Customise accordion group */ .theme-customise { border-top: 1px solid var(--t-border-default); margin-top: 1.5rem; padding-top: 1rem; } .theme-customise-summary { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 0.75rem 0; cursor: pointer; list-style: none; &::-webkit-details-marker { display: none; } } .theme-customise-label { font-size: 0.875rem; font-weight: 600; color: var(--admin-text-soft); transition: color 0.1s; } .theme-customise:hover .theme-customise-label, .theme-customise[open] .theme-customise-label { color: var(--t-text-primary); } .theme-customise-chevron { width: 1.25rem; height: 1.25rem; color: var(--admin-text-faint); transition: transform 0.2s; } .theme-customise[open] .theme-customise-chevron { transform: rotate(180deg); } /* Subsection group within customise accordion */ .theme-group { margin-bottom: 1.5rem; padding-bottom: 1.5rem; border-bottom: 1px solid var(--t-surface-sunken); } .theme-group-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 1rem; } .theme-group-icon { width: 1rem; height: 1rem; color: var(--admin-text-faint); } .theme-group-title { font-size: 0.875rem; font-weight: 600; color: var(--t-text-primary); } /* Current combination display */ .theme-combination { background: var(--t-surface-sunken); border-radius: 0.75rem; padding: 1rem; margin-top: 1.5rem; } .theme-combination-label { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--admin-text-faint); margin-bottom: 0.5rem; } .theme-combination-value { font-size: 0.875rem; color: var(--t-text-primary); line-height: 1.6; } .theme-combination-footnote { font-size: 0.75rem; color: var(--admin-text-faintest); margin-top: 0.5rem; } /* Preview area */ .theme-preview-area { flex: 1; padding: 1.5rem; display: flex; flex-direction: column; overflow: hidden; background: var(--t-surface-sunken); } .theme-preview-container { max-width: 1200px; margin-inline: auto; width: 100%; display: flex; flex-direction: column; flex: 1; min-height: 0; overflow: hidden; } /* Preview page tab switcher */ .theme-preview-tabs { display: flex; gap: 0.25rem; margin-bottom: 0.75rem; background: var(--t-border-default); padding: 0.25rem; border-radius: 0.5rem; width: fit-content; flex-shrink: 0; } .theme-preview-tab { padding: 0.5rem 1rem; font-size: 0.875rem; font-weight: 500; border-radius: 0.375rem; transition: all 0.15s; color: var(--admin-text-soft); &:hover { color: var(--t-text-primary); } } .theme-preview-tab-active { background: var(--t-surface-base); color: var(--t-text-primary); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); } /* Browser chrome frame */ .theme-browser-chrome { display: flex; align-items: center; background: linear-gradient(to bottom, var(--t-border-default), color-mix(in oklch, var(--t-border-default) 80%, transparent)); border: 1px solid color-mix(in oklch, var(--t-text-primary) 20%, transparent); border-bottom-color: var(--admin-text-ghost); border-radius: 0.625rem 0.625rem 0 0; padding: 0.625rem 0.875rem; gap: 0.875rem; flex-shrink: 0; } .theme-browser-dots { display: flex; gap: 0.5rem; } .theme-browser-dot { width: 0.75rem; height: 0.75rem; border-radius: 9999px; } .theme-browser-dot-close { background: #ff5f57; border: 1px solid #e14640; } .theme-browser-dot-min { background: #ffbd2e; border: 1px solid #dfa123; } .theme-browser-dot-max { background: #28c940; border: 1px solid #1aab29; } .theme-browser-url { flex: 1; display: flex; align-items: center; gap: 0.5rem; background: var(--t-surface-base); border: 1px solid color-mix(in oklch, var(--t-text-primary) 20%, transparent); border-radius: 0.375rem; padding: 0.3125rem 0.75rem; } .theme-browser-url-icon { width: 0.875rem; height: 0.875rem; color: var(--admin-text-faint); } .theme-browser-url-text { font-size: 0.875rem; color: var(--admin-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Preview content area */ .theme-preview-frame { overflow: auto; flex: 1; border-radius: 0 0 0.5rem 0.5rem; border: 1px solid color-mix(in oklch, var(--t-text-primary) 20%, transparent); border-top: none; position: relative; } /* Upload cancel button */ .theme-upload-cancel { color: var(--admin-text-faintest); &:hover { color: var(--admin-text-soft); } } /* Alt text hint for missing alt */ .theme-alt-warning { font-size: 0.75rem; color: var(--t-status-warning, #f59e0b); margin-top: 0.25rem; } /* Error text (upload errors) */ .theme-error-text { font-size: 0.75rem; color: var(--t-status-error, #dc2626); margin-top: 0.25rem; } /* Contrast warning for header backgrounds */ .theme-contrast-warning { display: flex; gap: 0.75rem; padding: 0.75rem 1rem; margin-top: 0.75rem; border-radius: 0.375rem; background: color-mix(in oklch, var(--t-status-warning) 12%, var(--t-surface-base)); font-size: 0.8125rem; line-height: 1.5; & .size-5 { color: var(--t-status-warning); flex-shrink: 0; margin-top: 0.125rem; } & strong { display: block; color: var(--t-text-primary); font-weight: 500; } & p { margin-top: 0.25rem; color: var(--admin-text-muted); } } /* Radio card selector (logo mode picker) */ .theme-radio-fieldset { border: none; padding: 0; margin: 0; } .theme-radio-card { position: relative; display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem; border: 1px solid var(--t-border-default); border-radius: 0.5rem; cursor: pointer; transition: border-color 0.15s, background 0.15s; &:hover { border-color: var(--admin-text-ghost); } &:has(:focus-visible) { outline: 2px solid var(--t-accent); outline-offset: 2px; } } .theme-radio-input { position: absolute; opacity: 0; pointer-events: none; } .theme-radio-card-active { border-color: var(--t-accent); background: color-mix(in oklch, var(--t-accent) 5%, transparent); } .theme-radio-dot { width: 1.25rem; height: 1.25rem; border-radius: 9999px; border: 2px solid var(--t-border-default); display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: border-color 0.15s; } .theme-radio-dot-active { border-color: var(--t-accent); } .theme-radio-dot-inner { width: 0.5rem; height: 0.5rem; border-radius: 9999px; background: transparent; transition: background 0.15s; } .theme-radio-dot-inner-active { background: var(--t-accent); } .theme-radio-title { font-size: 0.875rem; font-weight: 500; color: var(--t-text-primary); } /* Section-level spacing (lighter alternative to theme-panel — no background) */ .theme-section { margin-bottom: 1.5rem; } /* Block-level label (theme-slider-label inline by default, sometimes needs block) */ .theme-block-label { display: block; margin-bottom: 0.5rem; } /* Small text for checkbox/toggle labels in the sidebar */ .theme-check-text { font-size: 0.875rem; color: color-mix(in oklch, var(--t-text-primary) 80%, transparent); } /* Spacing between sub-controls within a panel */ .theme-subfield { margin-top: 0.75rem; } .theme-subfield-sm { margin-top: 0.5rem; } /* Customise accordion inner padding */ .theme-customise-body { padding-top: 1rem; } /* Collapse button pulled flush to sidebar edge inside header */ .theme-header .theme-collapse-btn { margin: -0.25rem -0.5rem 0 0; } /* Last group in a customise section (no border, tighter margin than theme-group) */ .theme-group-flush { margin-bottom: 1rem; } /* ── Settings editor (on-site editor Settings tab) ── */ .settings-editor-form { display: flex; flex-direction: column; gap: 0.25rem; } .settings-slug-preview { display: flex; align-items: center; gap: 0.25rem; } .settings-slug-preview .admin-input { flex: 1; } .settings-nav-options { padding-left: 1rem; border-left: 2px solid var(--admin-border); } .settings-nav-row { display: flex; gap: 0.75rem; } .settings-nav-field { flex: 1; } .settings-nav-field-sm { flex: 0 0 5rem; } .settings-actions { display: flex; align-items: center; gap: 0.75rem; padding-top: 0.5rem; } .settings-save-indicator { display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem; color: var(--admin-success); } .settings-save-error { color: var(--admin-error); } .settings-admin-link { padding-top: 0.5rem; border-top: 1px solid var(--admin-border); } .settings-info-view { display: flex; flex-direction: column; gap: 0.25rem; } /* ── Content width containers ── */ .admin-content-narrow { max-width: 32rem; } .admin-content-medium { max-width: 42rem; } /* ── Badge count (inline in tab/filter buttons) ── */ .admin-badge-count { margin-inline-start: 0.25rem; } /* ── Help and warning text ── */ .admin-help-text { font-size: 0.875rem; color: var(--admin-text-muted); } .admin-warning-text { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: #b45309; } /* ── Callout warning (amber env-locked) ── */ .admin-callout-warning { margin-top: 1.5rem; border-radius: 0.375rem; background: #fffbeb; padding: 1rem; box-shadow: inset 0 0 0 1px rgb(217 119 6 / 0.1); } .admin-callout-warning-body { display: flex; gap: 0.75rem; } .admin-callout-warning-icon { color: #d97706; flex-shrink: 0; margin-top: 0.125rem; } .admin-callout-warning-title { font-size: 0.875rem; font-weight: 500; color: #92400e; } .admin-callout-warning-desc { margin-top: 0.25rem; font-size: 0.875rem; color: #b45309; } /* ── Section heading variants ── */ .admin-section-heading { font-size: 1.125rem; font-weight: 600; } .admin-section-subheading { font-size: 1rem; font-weight: 600; } /* ── Section with border separator ── */ .admin-section-bordered { margin-top: 2rem; border-top: 1px solid var(--t-surface-sunken); padding-top: 1.5rem; } /* ── Email provider selection ── */ .admin-provider-group-desc { font-size: 0.75rem; color: var(--admin-text-muted); margin-top: 0.125rem; margin-bottom: 0.5rem; } .admin-provider-other { margin-top: 1rem; & > .card-radio-grid { margin-top: 0.5rem; } } .admin-provider-other-toggle { font-size: 0.8125rem; font-weight: 500; color: var(--admin-text-secondary); cursor: pointer; user-select: none; list-style: none; &::before { content: "\25B8 "; } } .admin-provider-other[open] > .admin-provider-other-toggle::before { content: "\25BE "; } .card-radio-recommended { background: oklch(0.45 0.15 145); color: white; font-weight: 500; } /* ── Numbered setup steps ── */ .admin-setup-step { display: flex; flex-direction: column; gap: 0.5rem; } .admin-setup-step-spaced { margin-top: 1.5rem; } .admin-setup-step-header { display: flex; align-items: center; gap: 0.625rem; font-size: 0.9375rem; font-weight: 600; color: var(--admin-text-primary); margin: 0; } .admin-setup-step-number { display: flex; align-items: center; justify-content: center; width: 1.5rem; height: 1.5rem; border-radius: 50%; background: var(--admin-accent, oklch(0.65 0.2 145)); color: white; font-size: 0.8125rem; font-weight: 600; flex-shrink: 0; } .admin-setup-step-desc { font-size: 0.8125rem; color: var(--admin-text-secondary); margin: 0; } .admin-setup-step-number-done { background: oklch(0.55 0.15 145); } .admin-setup-step-number-error { background: var(--t-status-error, oklch(0.6 0.2 25)); } .admin-test-error { font-size: 0.8125rem; font-weight: 600; color: var(--t-status-error, oklch(0.6 0.2 25)); margin: 0; } .admin-btn-error { border-color: var(--t-status-error, oklch(0.6 0.2 25)); color: var(--t-status-error, oklch(0.6 0.2 25)); } .admin-btn-danger { background: oklch(0.55 0.2 25); border-color: oklch(0.55 0.2 25); color: white; &:hover:not(:disabled) { background: oklch(0.5 0.22 25); border-color: oklch(0.5 0.22 25); } } /* ── Provider group headings ── */ .card-radio-group-heading { font-size: 0.8125rem; font-weight: 600; color: var(--admin-text-primary); margin: 1rem 0 0; } .card-radio-group-heading:first-of-type { margin-top: 0.5rem; } .card-radio-group-desc { font-size: 0.75rem; color: var(--admin-text-muted); margin: 0.125rem 0 0; } .card-radio-group-hint { font-weight: 500; } /* ── Email adapter config ── */ .admin-adapter-config { margin-top: 1.5rem; display: flex; flex-direction: column; gap: 1.5rem; } /* Hide the
summary — CSS :has(:checked) controls visibility instead */ .admin-adapter-config-summary { display: none; } /* Show only the adapter config matching the checked radio */ .admin-adapter-config[data-adapter] { display: none; } .admin-content-medium:has(#email-adapter-brevo:checked) [data-adapter="brevo"], .admin-content-medium:has(#email-adapter-sendgrid:checked) [data-adapter="sendgrid"], .admin-content-medium:has(#email-adapter-mailjet:checked) [data-adapter="mailjet"], .admin-content-medium:has(#email-adapter-mailersend:checked) [data-adapter="mailersend"], .admin-content-medium:has(#email-adapter-smtp:checked) [data-adapter="smtp"], .admin-content-medium:has(#email-adapter-postal:checked) [data-adapter="postal"] { display: flex; flex-direction: column; gap: 1.5rem; } /* ── Campaign form ── */ .admin-campaign-actions { display: flex; align-items: center; gap: 0.75rem; padding-top: 1rem; border-top: 1px solid var(--t-surface-sunken); } .admin-btn-success { background-color: var(--color-green-600); } .admin-preview-summary { font-size: 0.875rem; font-weight: 500; cursor: pointer; } .admin-preview-body { margin-top: 0.5rem; padding: 1rem; background: var(--t-surface-sunken); border-radius: 0.5rem; font-size: 0.875rem; white-space: pre-wrap; overflow: auto; max-height: 16rem; } /* ── Navigation editor ── */ .admin-nav-layout { margin-top: 1.5rem; max-width: 40rem; display: flex; flex-direction: column; gap: 2rem; } .admin-nav-empty { font-size: 0.875rem; color: var(--admin-text-faint); padding: 1rem 0; } .admin-nav-actions { margin-top: 0.75rem; display: flex; gap: 0.5rem; } .nav-editor-dropdown-wrap { position: relative; } .nav-editor-dropdown-slug { font-size: 0.75rem; color: var(--admin-text-faintest); } .nav-editor-select { flex: 1; min-width: 0; font-size: 0.875rem; padding: 0.375rem 0.5rem; } .nav-editor-item { flex-wrap: wrap; } .nav-editor-external { flex-basis: 100%; padding-top: 0.5rem; display: flex; flex-direction: column; gap: 0.25rem; } .nav-editor-error { display: flex; align-items: center; gap: 0.25rem; font-size: 0.75rem; color: var(--t-text-error); } .admin-input-error { border-color: var(--t-border-error); } /* ── Page editor ── */ .admin-editor-badges { margin-top: 1rem; display: flex; gap: 0.5rem; flex-wrap: wrap; } /* ── Product show ── */ .admin-product-header { display: flex; align-items: center; gap: 0.75rem; margin-top: 0.25rem; } .admin-product-title { font-size: 1.5rem; font-weight: 700; } .admin-card-spaced { margin-top: 1.5rem; } /* ── Products table ── */ .admin-product-name { font-weight: 500; } /* ── Visibility / availability icon colours ── */ .admin-icon-positive { color: #16a34a; } .admin-icon-muted { color: var(--admin-text-ghost); } /* ── Filter select label & wrapper ── */ .admin-filter-label { font-size: 0.75rem; margin-bottom: 0.125rem; display: block; } .admin-filter-select { width: auto; } .admin-filter-select-wide { width: auto; flex: 1; min-width: 12rem; } /* ── Table row clickable ── */ .admin-table-row-clickable { cursor: pointer; } /* ── Tab actions bar (right-aligned above table) ── */ .admin-tab-actions { display: flex; justify-content: flex-end; margin-bottom: 1rem; } /* ── Filter row with space-between ── */ .admin-filter-row-between { justify-content: space-between; } /* ── Form layout ── */ .admin-form-stack { display: flex; flex-direction: column; gap: 1.5rem; max-width: 32rem; } .admin-form-sub { display: flex; flex-direction: column; gap: 1rem; padding-inline-start: 1.5rem; } /* ── Inline input that fills remaining space ── */ .admin-input-fill { flex: 1; } /* ── Source list (dead links) ── */ .admin-source-list { list-style: none; padding: 0; margin: 0; & li + li { margin-top: 0.25rem; } } /* ── Truncated cell ── */ .admin-cell-truncate { max-width: 20rem; } /* ── Text weight modifier ── */ .admin-text-medium { font-weight: 500; } /* ── Read-only actions (campaign form) ── */ .admin-readonly-actions { padding-top: 1rem; border-top: 1px solid var(--t-surface-sunken); } /* ── Row modifiers ── */ .admin-row-between { justify-content: space-between; } .admin-row-sm { --admin-row-gap: 0.25rem; } .admin-row-xl { --admin-row-gap: 1rem; } /* ── Bold text weight ── */ .admin-text-bold { font-weight: 700; } /* ── Semantic colour text ── */ .admin-text-warning { color: var(--t-status-warning, #d97706); } .admin-text-error { color: var(--t-status-error, #ef4444); } /* ── Right-aligned table cells ── */ .admin-cell-end { text-align: end; } .admin-cell-numeric { text-align: end; font-variant-numeric: tabular-nums; } /* ── Small inline code ── */ .admin-code-sm { font-size: 0.75rem; } .admin-code-break { font-size: 0.75rem; word-break: break-all; } /* ── Section body flush (no top margin) ── */ .admin-section-desc-flush { margin-top: 0; } /* ── Separator (border-top with compact padding) ── */ .admin-separator { border-top: 1px solid var(--t-surface-sunken); padding-top: 0.75rem; } .admin-separator-lg { border-top: 1px solid var(--t-surface-sunken); padding-top: 1rem; } .admin-separator-xl { border-top: 1px solid var(--t-surface-sunken); padding-top: 1.5rem; } /* ── Button body (compact top margin for form buttons) ── */ .admin-form-actions-sm { margin-top: 0.75rem; } /* ── Flex fill (take remaining space) ── */ .admin-fill { flex: 1; } /* ── Larger input (prominent fields like shop name) ── */ .admin-input-lg { padding: 0.75rem 1rem; font-size: 1rem; } /* ═══════════════════════════════════════════════════════════════════ Analytics ═══════════════════════════════════════════════════════════════════ */ .analytics-periods { display: flex; gap: 0.25rem; margin-top: 1rem; align-items: center; } .analytics-export { margin-left: auto; } .analytics-filters { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; margin-top: 1rem; } .analytics-filter-chip { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.25rem 0.5rem; font-size: 0.75rem; background: var(--color-base-200, #e5e5e5); border-radius: 0.25rem; } .analytics-filter-remove { cursor: pointer; opacity: 0.6; line-height: 1; } .analytics-tab-heading { font-size: 0.875rem; font-weight: 600; margin-bottom: 0.75rem; } .analytics-tab-heading-spaced { font-size: 0.875rem; font-weight: 600; margin: 1.5rem 0 0.75rem; } .analytics-chart-card { padding: 1rem; } .analytics-tab-bar { display: flex; gap: 0.25rem; margin-top: 1.5rem; flex-wrap: wrap; } .analytics-tab-panel { margin-top: 0.75rem; padding: 1rem; } .analytics-empty { text-align: center; padding: 1.5rem; color: color-mix(in oklch, var(--color-base-content) 40%, transparent); } /* Chart layout */ .analytics-chart-grid { display: grid; grid-template-columns: auto 1fr; gap: 0 0.5rem; position: relative; } .analytics-tooltip { display: none; position: absolute; top: -1.75rem; z-index: 10; padding: 0.25rem 0.5rem; font-size: 0.75rem; font-weight: 500; white-space: nowrap; background: var(--color-base-content, #1e1e1e); color: var(--color-base-100, #fff); border-radius: 0.25rem; pointer-events: none; font-variant-numeric: tabular-nums; } .analytics-y-labels { display: flex; flex-direction: column; justify-content: space-between; align-items: flex-end; height: 8rem; font-size: 0.75rem; color: color-mix(in oklch, var(--color-base-content) 50%, transparent); } .analytics-chart-area { position: relative; height: 8rem; } .analytics-gridline-mid { position: absolute; top: 50%; left: 0; right: 0; border-top: 1px dashed color-mix(in oklch, var(--color-base-content) 12%, transparent); } .analytics-gridline-bottom { position: absolute; bottom: 0; left: 0; right: 0; border-top: 1px solid color-mix(in oklch, var(--color-base-content) 15%, transparent); } .analytics-bars { display: flex; align-items: flex-end; height: 100%; } .analytics-bar { flex: 1; background: var(--color-primary, #4f46e5); opacity: 0.8; border-radius: 1px 1px 0 0; min-width: 0; } .analytics-x-labels { display: flex; justify-content: space-between; padding-top: 0.25rem; font-size: 0.75rem; color: color-mix(in oklch, var(--color-base-content) 50%, transparent); } .analytics-delta { font-size: 0.75rem; font-weight: 500; white-space: nowrap; } /* Funnel */ .analytics-funnel { display: flex; flex-direction: column; gap: 0.5rem; } .analytics-funnel-step { display: flex; align-items: center; gap: 0.75rem; } .analytics-funnel-label { width: 7rem; font-size: 0.8125rem; text-align: right; flex-shrink: 0; } .analytics-funnel-bar { height: 2rem; background: var(--color-primary, #4f46e5); border-radius: 0.25rem; display: flex; align-items: center; padding-left: 0.5rem; } .analytics-funnel-value { font-size: 0.75rem; font-weight: 600; color: white; } .analytics-funnel-rate { font-size: 0.8125rem; font-weight: 600; } .analytics-funnel-summary { margin-top: 0.75rem; font-size: 0.875rem; display: flex; gap: 0.5rem; flex-wrap: wrap; } /* ── Stat card (icon + value + label) ── */ .admin-stat-card-body { display: flex; align-items: center; gap: 0.75rem; padding: 1rem; } .admin-stat-icon { background: var(--color-base-200, #e5e5e5); border-radius: 0.5rem; padding: 0.5rem; flex-shrink: 0; } .admin-stat-value-row { display: flex; align-items: baseline; gap: 0.5rem; } /* ═══════════════════════════════════════════════════════════════════ Dashboard ═══════════════════════════════════════════════════════════════════ */ .dashboard-section { margin-top: 2rem; } .dashboard-section-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1rem; } .dashboard-view-all { font-size: 0.875rem; color: color-mix(in oklch, var(--color-base-content) 60%, transparent); } .dashboard-recent-orders { overflow-x: auto; } .dashboard-stat-link { display: block; text-decoration: none; color: inherit; } .setup-complete-actions { display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; } .dashboard-empty-orders { border: 1px solid var(--color-base-200, #e5e5e5); border-radius: 0.5rem; padding: 2rem; text-align: center; color: color-mix(in oklch, var(--color-base-content) 60%, transparent); } .dashboard-empty-icon { margin: 0 auto 0.75rem; width: 2.5rem; opacity: 0.3; } /* ═══════════════════════════════════════════════════════════════════ Order show ═══════════════════════════════════════════════════════════════════ */ .order-detail-grid { margin-top: 1.5rem; &.admin-grid { --admin-grid-min: 20rem; --admin-grid-gap: 1.5rem; } } .order-timeline-actions { margin-top: 0.5rem; margin-bottom: 1rem; } .order-tracking { margin-bottom: 1rem; font-size: 0.875rem; } .order-timeline-empty { padding-block: 1rem; margin-top: 0; } .order-total-row { font-size: 1.125rem; } /* ── Foundational utilities ── */ /* Classes that can't be replaced with inline styles because they're passed via class attributes to components like <.icon> */ .size-3 { width: 0.75rem; height: 0.75rem; } .size-4 { width: 1rem; height: 1rem; } .size-5 { width: 1.25rem; height: 1.25rem; } .size-6 { width: 1.5rem; height: 1.5rem; } .size-8 { width: 2rem; height: 2rem; } .size-10 { width: 2.5rem; height: 2.5rem; } .size-12 { width: 3rem; height: 3rem; } .shrink-0 { flex-shrink: 0; } .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .ml-1 { margin-inline-start: 0.25rem; } .external-link-icon.external-link-icon { width: 0.75em; height: 0.75em; margin-inline-start: 0.25em; vertical-align: baseline; opacity: 0.6; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } @keyframes spin { to { transform: rotate(360deg); } } .animate-spin { animation: spin 1s linear infinite; } @media (prefers-reduced-motion: reduce) { .animate-spin { animation: none; } } @media (prefers-reduced-motion: no-preference) { .motion-safe\:animate-spin { animation: spin 1s linear infinite; } } /* Phoenix LiveView JS transition utilities */ .transition-all { transition-property: all; } .ease-out { transition-timing-function: cubic-bezier(0, 0, 0.2, 1); } .ease-in { transition-timing-function: cubic-bezier(0.4, 0, 1, 1); } .duration-200 { transition-duration: 200ms; } .duration-300 { transition-duration: 300ms; } .opacity-0 { opacity: 0; } .opacity-100 { opacity: 1; } .translate-y-0 { translate: 0 0; } .translate-y-4 { translate: 0 1rem; } @media (min-width: 640px) { .sm\:translate-y-0 { translate: 0 0; } .sm\:scale-95 { scale: 0.95; } .sm\:scale-100 { scale: 1; } } /* ── Backup page ── */ .admin-backup { max-width: 48rem; } .admin-link { display: inline-flex; align-items: center; gap: 0.25rem; font-size: 0.875rem; color: var(--t-primary); cursor: pointer; background: none; border: none; padding: 0; &:hover { text-decoration: underline; } } .admin-error { color: var(--admin-error); font-size: 0.875rem; margin-bottom: 0.75rem; } .admin-table-compact { font-size: 0.8125rem; th, td { padding: 0.5rem 0.75rem; } } .backup-tables { margin-top: 1rem; max-height: 20rem; overflow-y: auto; border: 1px solid var(--t-border-subtle); border-radius: var(--radius-md); } .backup-tables .admin-table { margin: 0; } .backup-actions { display: flex; gap: 0.5rem; margin-top: 0.5rem; } .backup-list { display: flex; flex-direction: column; gap: 0.5rem; } .backup-item { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.625rem 0.875rem; background: var(--t-surface-raised); border-radius: var(--radius-md); } .backup-item-info { display: flex; flex-direction: column; gap: 0.125rem; min-width: 0; } .backup-item-date { font-size: 0.875rem; font-weight: 500; } .backup-item-meta { font-size: 0.75rem; color: var(--admin-text-muted); } .backup-item-actions { display: flex; align-items: center; gap: 0.375rem; flex-shrink: 0; } .backup-item-confirm { font-size: 0.8125rem; color: var(--admin-text-muted); margin-right: 0.25rem; } .backup-progress { display: flex; align-items: center; gap: 0.75rem; padding: 1rem; background: var(--t-surface-raised); border-radius: var(--radius-md); } .backup-progress-text { font-weight: 500; } .backup-progress-hint { font-size: 0.8125rem; color: var(--admin-text-muted); } .backup-dropzone { border: 2px dashed var(--t-border-subtle); border-radius: var(--radius-md); padding: 1.5rem; text-align: center; transition: border-color 0.15s, background-color 0.15s; color: var(--admin-text-muted); &:hover, &.phx-drop-target { border-color: var(--t-primary); background: oklch(from var(--t-primary) l c h / 0.05); } } .backup-dropzone-content { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; } .backup-dropzone-link { color: var(--t-primary); cursor: pointer; text-decoration: underline; } .backup-upload-entry { display: flex; align-items: center; gap: 1rem; padding: 0.625rem 0.875rem; background: var(--t-surface-raised); border-radius: var(--radius-md); margin-top: 0.75rem; font-size: 0.875rem; progress { flex: 1; height: 0.375rem; border-radius: 9999px; overflow: hidden; background: var(--t-surface-inset); &::-webkit-progress-bar { background: var(--t-surface-inset); } &::-webkit-progress-value { background: var(--t-primary); } &::-moz-progress-bar { background: var(--t-primary); } } } .backup-comparison { margin-top: 0.5rem; } .backup-comparison-grid { display: grid; grid-template-columns: 1fr auto 1fr; gap: 0.75rem; align-items: start; margin-bottom: 1rem; } .backup-comparison-col { padding: 0.75rem 1rem; background: var(--t-surface-raised); border-radius: var(--radius-md); } .backup-comparison-label { font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--admin-text-muted); margin-bottom: 0.5rem; } .backup-comparison-arrow { display: flex; align-items: center; justify-content: center; padding-top: 1.5rem; color: var(--admin-text-muted); } .backup-comparison-stats { display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.8125rem; > div { display: flex; justify-content: space-between; gap: 1rem; } dt { color: var(--admin-text-muted); } dd { font-weight: 500; font-variant-numeric: tabular-nums; } } .backup-validation { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.75rem; border-radius: var(--radius-md); font-size: 0.8125rem; margin-bottom: 0.75rem; } .backup-validation-ok { background: oklch(0.95 0.1 145); color: oklch(0.35 0.15 145); } .backup-validation-error { background: oklch(0.95 0.05 25); color: oklch(0.35 0.1 25); } .backup-warning { padding: 0.75rem 1rem; background: oklch(0.96 0.03 60); border-radius: var(--radius-md); font-size: 0.875rem; color: oklch(0.35 0.1 60); p { margin-bottom: 0.75rem; } } } /* @layer admin */