/* Admin component styles — uses --t-* theme tokens directly. */ @layer admin { /* ── Layout ── */ .admin-layout { display: grid; grid-template-columns: 0 1fr; height: 100%; } .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%; 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-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; } } .admin-btn-primary { background-color: var(--t-accent); color: var(--t-text-inverse); } .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-icon { padding: 0.5rem; aspect-ratio: 1; border-radius: 0.375rem; } .admin-btn-icon-round { padding: 0.25rem; aspect-ratio: 1; border-radius: 9999px; } /* ── 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; } /* ── 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: color-mix(in oklch, var(--t-text-primary) 60%, transparent); 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); } /* ── 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-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); &: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-toast { position: fixed; top: 1rem; inset-inline-end: 1rem; z-index: 100; } .admin-alert { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.75rem 1rem; border-radius: 0.5rem; font-size: 0.875rem; line-height: 1.5; } .admin-alert-info { background-color: color-mix(in oklch, var(--t-status-info) 12%, var(--t-surface-base)); color: var(--t-status-info); border: 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: 1px solid color-mix(in oklch, var(--t-status-error) 25%, var(--t-surface-base)); } .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: color-mix(in oklch, var(--t-text-primary) 70%, transparent); } .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-danger { background-color: color-mix(in oklch, var(--t-status-error, #ef4444) 15%, transparent); color: var(--t-status-error, #dc2626); } .admin-badge-neutral { background-color: var(--t-surface-sunken); color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); } /* ── 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); } } .admin-spinner { display: inline-block; width: 1.25rem; height: 1.25rem; border: 2px solid var(--t-border-default); border-top-color: var(--t-accent); border-radius: 9999px; animation: admin-spin 0.6s linear infinite; } /* ── Divider ── */ .admin-divider { display: flex; align-items: center; gap: 1rem; color: color-mix(in oklch, var(--t-text-primary) 40%, transparent); 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; } /* ── Form error text ── */ .admin-error { color: var(--t-status-error); } /* ── 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: color-mix(in oklch, var(--t-text-primary) 70%, transparent); border: 1px solid var(--t-border-default); } /* ── Swap (visibility toggle) ── */ .admin-swap { position: relative; display: inline-flex; & .admin-swap-on, & .admin-swap-off { display: none; } & .admin-swap-off { display: inline-flex; } &.active .admin-swap-on { display: inline-flex; } &.active .admin-swap-off { display: none; } } /* ── 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; } /* ── Setup page ── */ .setup-page { max-width: 36rem; margin: 0 auto; padding: 2rem 1rem; } .setup-header { text-align: center; margin-bottom: 2rem; } .setup-title { font-size: 1.5rem; font-weight: 700; line-height: 1.2; } .setup-subtitle { color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); 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: color-mix(in oklch, var(--t-text-primary) 60%, transparent); } .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: color-mix(in oklch, var(--t-text-primary) 60%, transparent); } .setup-card-body { margin-top: 1rem; padding-inline-start: 2.5rem; } /* Setup: check inbox phase */ .setup-check-inbox { text-align: center; padding: 1rem 0; } .setup-inbox-icon { color: var(--t-text-primary, #171717); margin: 0 auto 0.75rem; } .setup-inbox-heading { font-size: 1.125rem; font-weight: 600; margin-bottom: 0.25rem; } .setup-inbox-detail { font-size: 0.875rem; color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); margin-bottom: 1rem; } .setup-start-over { font-size: 0.8125rem; color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); margin-top: 1rem; } .setup-hint { font-size: 0.8125rem; color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); margin-bottom: 0.75rem; } .setup-link { color: var(--t-text-primary, #171717); text-decoration: underline; } .setup-key-hint { font-size: 0.75rem; color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); 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; } /* 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; } .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: color-mix(in oklch, var(--t-text-primary) 40%, transparent); } } &:active:not(:has(:disabled)) { background: color-mix(in oklch, var(--t-surface-sunken) 50%, transparent); } &.card-radio-card-selected { 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 { font-size: 0.875rem; font-weight: 600; } .card-radio-description { font-size: 0.75rem; color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); } .card-radio-badge { font-size: 0.6875rem; padding: 0.125rem 0.375rem; border-radius: 9999px; background: var(--t-surface-sunken, #e5e5e5); color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); } .card-radio-link { font-size: 0.6875rem; color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); 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: color-mix(in oklch, var(--t-text-primary) 70%, transparent); 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: color-mix(in oklch, var(--t-text-primary) 60%, transparent); margin: 0.25rem 0 1rem; } /* ── 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; margin-bottom: 1rem; } .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: color-mix(in oklch, var(--t-text-primary) 60%, transparent); } .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: center; gap: 0.75rem; padding: 0.5rem 0; } .admin-checklist-check { display: flex; align-items: center; justify-content: center; width: 1.25rem; height: 1.25rem; 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 { flex: 1; font-size: 0.875rem; } .admin-checklist-label-done { color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); } .admin-checklist-action { flex-shrink: 0; } .admin-checklist-footer { display: flex; align-items: center; justify-content: space-between; margin-top: 1rem; padding-top: 0.75rem; border-top: 1px solid var(--t-surface-sunken, #e5e5e5); } /* ── 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: color-mix(in oklch, var(--t-text-primary) 50%, transparent); 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: color-mix(in oklch, var(--t-text-primary) 60%, transparent); } .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: color-mix(in oklch, var(--t-text-primary) 50%, transparent); } .page-card-arrow { flex-shrink: 0; color: color-mix(in oklch, var(--t-text-primary) 30%, transparent); } .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: color-mix(in oklch, var(--t-text-primary) 30%, transparent); 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: color-mix(in oklch, var(--t-text-primary) 30%, transparent); 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.5rem; margin-top: 1.5rem; } .block-list-empty { text-align: center; padding: 2rem; color: color-mix(in oklch, var(--t-text-primary) 50%, transparent); font-size: 0.875rem; border: 1px dashed var(--t-border-default); border-radius: 0.5rem; } .block-card { padding: 0.5rem 0.75rem; border: 1px solid var(--t-border-default); border-radius: 0.5rem; 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); } } .block-card-position { display: flex; align-items: center; justify-content: center; width: 1.5rem; height: 1.5rem; border-radius: 0.25rem; font-size: 0.75rem; font-weight: 600; color: color-mix(in oklch, var(--t-text-primary) 50%, transparent); flex-shrink: 0; } .block-card-icon { display: flex; align-items: center; color: color-mix(in oklch, var(--t-text-primary) 60%, transparent); flex-shrink: 0; } .block-card-info { flex: 1; min-width: 0; } .block-card-name { font-size: 0.875rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .block-card-preview { display: block; font-size: 0.75rem; color: color-mix(in oklch, var(--t-text-primary) 50%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .block-card-controls { display: flex; align-items: center; gap: 0.125rem; flex-shrink: 0; } .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: color-mix(in oklch, var(--t-text-primary) 50%, transparent); font-size: 0.8125rem; } /* Block card header + expanded state */ .block-card-header { display: flex; align-items: center; gap: 0.5rem; width: 100%; } .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: color-mix(in oklch, var(--t-text-primary) 60%, transparent); 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; } /* ── Live editor layout (sidebar on shop pages) ── */ .page-editor-live { display: flex; min-height: 100vh; } .page-editor-sidebar { position: fixed; top: 0; left: 0; bottom: 0; width: 360px; background: var(--t-surface-base); border-right: 1px solid var(--t-border-default); overflow-y: auto; z-index: 40; box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1); padding: 1rem; transition: transform 0.25s ease; transform: translateX(0); } /* Hidden sidebar — slides off-screen */ [data-sidebar-open="false"] .page-editor-sidebar { transform: translateX(-100%); box-shadow: none; } .page-editor-sidebar-header { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.75rem; } .page-editor-sidebar-title { font-size: 1rem; font-weight: 600; flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .page-editor-sidebar-actions { display: flex; align-items: center; gap: 0.25rem; flex-shrink: 0; } .page-editor-sidebar-dirty { margin-bottom: 0.5rem; } /* Picker inside the editor sidebar — grid scrolls within a capped height */ .page-editor-sidebar .block-picker-overlay { position: static; background: none; } .page-editor-sidebar .block-picker { border-radius: 0; max-height: none; padding: 0; } .page-editor-sidebar .block-picker-grid { max-height: 45dvh; overflow-y: auto; } .page-editor-content { flex: 1; margin-left: 360px; min-width: 0; transition: margin-left 0.25s ease; } /* Content goes full-width when sidebar is hidden */ [data-sidebar-open="false"] .page-editor-content { margin-left: 0; } /* Clickable backdrop to dismiss the sidebar */ .page-editor-backdrop { position: fixed; inset: 0; z-index: 39; background: rgba(0, 0, 0, 0.15); cursor: pointer; } /* Mobile: sidebar overlays content, no margin push */ @media (max-width: 63.99em) { .page-editor-sidebar { width: 85%; max-width: 360px; padding-bottom: calc(4rem + env(safe-area-inset-bottom, 0px) + 1rem); } .page-editor-content { margin-left: 0; } } /* ═══════════════════════════════════════════════════════════════════ 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-empty { display: flex; align-items: center; gap: 0.5rem; padding: 0.75rem; border: 2px dashed var(--t-border-default); border-radius: 0.375rem; color: var(--t-text-primary); opacity: 0.5; font-size: 0.8125rem; } .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: color-mix(in oklch, var(--t-text-primary) 50%, transparent); 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: color-mix(in oklch, var(--t-text-primary) 60%, transparent); 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-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; } } } /* @layer admin */