/* ========================================================================== Image Manager Components ========================================================================== */ /* Upload Area Styles ========================================================================== */ .image-upload-area { position: relative; border: 2px dashed var(--color-border-subtle); border-radius: var(--border-radius-lg); background: var(--color-surface-subtle); transition: all 0.2s ease; min-height: 200px; } .image-upload-area:hover, .image-upload-area:focus-within { border-color: var(--color-primary); background: var(--color-surface-elevated); } .image-upload-area--drag-over { border-color: var(--color-success); background: var(--color-success-subtle); transform: scale(1.02); } .upload-area__content { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--space-xl); text-align: center; gap: var(--space-md); } .upload-area__icon { color: var(--color-text-subtle); opacity: 0.6; } .upload-area__text h3 { margin: 0 0 var(--space-xs) 0; color: var(--color-text-primary); font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold); } .upload-area__text p { margin: 0; color: var(--color-text-subtle); font-size: var(--font-size-sm); } .upload-area__button { background: var(--color-primary); color: var(--color-primary-contrast); border: none; border-radius: var(--border-radius-md); padding: var(--space-sm) var(--space-lg); font-size: var(--font-size-base); font-weight: var(--font-weight-medium); cursor: pointer; transition: all 0.2s ease; } .upload-area__button:hover { background: var(--color-primary-hover); transform: translateY(-1px); } .upload-area__preview { display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: var(--space-sm); padding: var(--space-md); border-top: 1px solid var(--color-border-subtle); } .preview-item { position: relative; aspect-ratio: 1; border-radius: var(--border-radius-md); overflow: hidden; background: var(--color-surface-elevated); } .preview-item__image { width: 100%; height: 100%; object-fit: cover; } .preview-item__info { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(transparent, rgba(0, 0, 0, 0.8)); padding: var(--space-xs); color: white; font-size: var(--font-size-xs); } .preview-item__name { font-weight: var(--font-weight-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .preview-item__size { opacity: 0.8; font-size: var(--font-size-xs); } .upload-area__progress { position: absolute; bottom: 0; left: 0; right: 0; background: var(--color-surface-elevated); border-top: 1px solid var(--color-border-subtle); padding: var(--space-md); border-radius: 0 0 var(--border-radius-lg) var(--border-radius-lg); } .progress-bar { background: var(--color-background-muted); border-radius: var(--border-radius-full); height: 8px; overflow: hidden; margin-bottom: var(--space-xs); } .progress-bar__fill { background: var(--color-primary); height: 100%; border-radius: var(--border-radius-full); transition: width 0.3s ease; width: 0%; } .progress-text { font-size: var(--font-size-sm); color: var(--color-text-subtle); text-align: center; } /* Image Gallery Styles ========================================================================== */ .image-gallery { display: flex; flex-direction: column; gap: var(--space-lg); } .gallery__controls { display: flex; gap: var(--space-md); align-items: center; flex-wrap: wrap; } .gallery__search-wrapper { position: relative; flex: 1; min-width: 200px; } .gallery__search { width: 100%; padding: var(--space-sm) var(--space-md); border: 1px solid var(--color-border-subtle); border-radius: var(--border-radius-md); font-size: var(--font-size-base); background: var(--color-surface); } .gallery__search:focus { border-color: var(--color-primary); outline: none; box-shadow: 0 0 0 3px var(--color-primary-alpha-20); } .gallery__search-clear { position: absolute; right: var(--space-sm); top: 50%; transform: translateY(-50%); background: none; border: none; font-size: var(--font-size-lg); color: var(--color-text-subtle); cursor: pointer; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; border-radius: var(--border-radius-sm); } .gallery__search-clear:hover { background: var(--color-surface-subtle); color: var(--color-text-primary); } .gallery__sort-wrapper { display: flex; align-items: center; gap: var(--space-sm); } .gallery__sort { padding: var(--space-sm) var(--space-md); border: 1px solid var(--color-border-subtle); border-radius: var(--border-radius-md); background: var(--color-surface); font-size: var(--font-size-base); } .gallery__grid { display: grid; grid-template-columns: repeat(var(--columns, 4), 1fr); gap: var(--space-lg); grid-auto-rows: min-content; } @media (max-width: 1200px) { .gallery__grid { grid-template-columns: repeat(3, 1fr); } } @media (max-width: 768px) { .gallery__grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-md); } } @media (max-width: 480px) { .gallery__grid { grid-template-columns: 1fr; } } .gallery__item { position: relative; border-radius: var(--border-radius-lg); overflow: hidden; background: var(--color-surface); box-shadow: var(--shadow-sm); transition: all 0.2s ease; } .gallery__item:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); } .gallery__item--selected { box-shadow: 0 0 0 3px var(--color-primary); } .gallery__item-inner { display: flex; flex-direction: column; } .gallery__item-image { position: relative; aspect-ratio: 4/3; overflow: hidden; } .gallery__item-image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.2s ease; } .gallery__item:hover .gallery__item-image img { transform: scale(1.05); } .gallery__item-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.6); display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.2s ease; } .gallery__item:hover .gallery__item-overlay { opacity: 1; } .gallery__item-actions { display: flex; gap: var(--space-sm); } .action-btn { background: rgba(255, 255, 255, 0.9); border: none; border-radius: var(--border-radius-full); width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.2s ease; font-size: var(--font-size-base); } .action-btn:hover { background: white; transform: scale(1.1); } .action-btn.select-btn { background: var(--color-primary); color: white; } .action-btn.delete-btn:hover { background: var(--color-danger); color: white; } .gallery__item-info { padding: var(--space-md); } .gallery__item-name { font-weight: var(--font-weight-medium); margin-bottom: var(--space-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .gallery__item-meta { display: flex; gap: var(--space-sm); font-size: var(--font-size-xs); color: var(--color-text-subtle); } .meta-item { background: var(--color-surface-subtle); padding: var(--space-xs) var(--space-sm); border-radius: var(--border-radius-sm); } .gallery__pagination { display: flex; justify-content: center; padding: var(--space-lg) 0; } .gallery__load-more { background: var(--color-primary); color: var(--color-primary-contrast); border: none; border-radius: var(--border-radius-md); padding: var(--space-md) var(--space-xl); font-size: var(--font-size-base); font-weight: var(--font-weight-medium); cursor: pointer; transition: all 0.2s ease; } .gallery__load-more:hover:not(:disabled) { background: var(--color-primary-hover); transform: translateY(-1px); } .gallery__load-more:disabled { opacity: 0.6; cursor: not-allowed; } .gallery__loading { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--space-xl); color: var(--color-text-subtle); } .gallery__empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--space-xxl); text-align: center; color: var(--color-text-subtle); } .empty-state__icon { margin-bottom: var(--space-lg); opacity: 0.5; } .gallery__empty h3 { margin: 0 0 var(--space-sm) 0; color: var(--color-text-primary); } .gallery__empty p { margin: 0; font-size: var(--font-size-base); } .gallery__error { margin: var(--space-md) 0; } .error-message { background: var(--color-danger-subtle); border: 1px solid var(--color-danger); border-radius: var(--border-radius-md); padding: var(--space-md); display: flex; align-items: center; gap: var(--space-sm); } .error-icon { font-size: var(--font-size-lg); } .error-text { flex: 1; color: var(--color-danger-contrast); } .error-close { background: none; border: none; font-size: var(--font-size-lg); color: var(--color-danger-contrast); cursor: pointer; opacity: 0.7; } .error-close:hover { opacity: 1; } /* Image Modal Styles ========================================================================== */ .image-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000; display: none; } .image-modal--open { display: block; } .image-modal__backdrop { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); backdrop-filter: blur(4px); } .image-modal__container { position: relative; width: 100%; height: 100%; display: flex; flex-direction: column; background: var(--color-surface); animation: modalSlideIn 0.3s ease; } @keyframes modalSlideIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .image-modal__header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-lg); border-bottom: 1px solid var(--color-border-subtle); background: var(--color-surface-elevated); } .image-modal__title { margin: 0; font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; margin-right: var(--space-md); } .image-modal__actions { display: flex; gap: var(--space-sm); } .modal-btn { border: none; border-radius: var(--border-radius-md); padding: var(--space-sm); cursor: pointer; transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; } .modal-btn--primary { background: var(--color-primary); color: var(--color-primary-contrast); } .modal-btn--secondary { background: var(--color-surface-subtle); color: var(--color-text-primary); } .modal-btn--danger { background: var(--color-danger-subtle); color: var(--color-danger); } .modal-btn--ghost { background: transparent; color: var(--color-text-subtle); } .modal-btn--small { width: auto; height: auto; padding: var(--space-xs) var(--space-sm); font-size: var(--font-size-sm); } .modal-btn--success { background: var(--color-success) !important; color: var(--color-success-contrast) !important; } .modal-btn:hover { opacity: 0.8; transform: translateY(-1px); } .modal-close { background: transparent; border: none; color: var(--color-text-subtle); cursor: pointer; padding: var(--space-sm); } .image-modal__content { display: flex; flex: 1; overflow: hidden; } .image-modal__image-container { flex: 1; display: flex; align-items: center; justify-content: center; background: var(--color-background-muted); position: relative; overflow: hidden; } .image-modal__image { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--border-radius-md); } .image-modal__loading { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; gap: var(--space-md); } .image-modal__sidebar { width: 400px; background: var(--color-surface-elevated); border-left: 1px solid var(--color-border-subtle); overflow-y: auto; display: flex; flex-direction: column; } @media (max-width: 1024px) { .image-modal__content { flex-direction: column; } .image-modal__sidebar { width: 100%; max-height: 40%; border-left: none; border-top: 1px solid var(--color-border-subtle); } } .image-modal__metadata, .image-modal__alt-text, .image-modal__variants { padding: var(--space-lg); border-bottom: 1px solid var(--color-border-subtle); } .image-modal__metadata h3, .image-modal__alt-text h3, .image-modal__variants h3 { margin: 0 0 var(--space-md) 0; font-size: var(--font-size-base); font-weight: var(--font-weight-semibold); color: var(--color-text-primary); } .metadata-grid { display: grid; gap: var(--space-sm); } .metadata-item { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-sm); align-items: center; } .metadata-item label { font-size: var(--font-size-sm); color: var(--color-text-subtle); font-weight: var(--font-weight-medium); } .metadata-value { font-size: var(--font-size-sm); color: var(--color-text-primary); } .metadata-value--hash { font-family: var(--font-mono); word-break: break-all; background: var(--color-surface-subtle); padding: var(--space-xs); border-radius: var(--border-radius-sm); } .alt-text-input { width: 100%; min-height: 80px; padding: var(--space-sm); border: 1px solid var(--color-border-subtle); border-radius: var(--border-radius-md); font-size: var(--font-size-sm); font-family: inherit; resize: vertical; background: var(--color-surface); } .alt-text-input:focus { border-color: var(--color-primary); outline: none; box-shadow: 0 0 0 3px var(--color-primary-alpha-20); } .alt-text-actions { margin-top: var(--space-sm); } .variants-list { display: flex; flex-direction: column; gap: var(--space-sm); } .variant-item { display: flex; align-items: center; justify-content: space-between; padding: var(--space-sm); background: var(--color-surface-subtle); border-radius: var(--border-radius-md); } .variant-info strong { display: block; font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); } .variant-dimensions { font-size: var(--font-size-xs); color: var(--color-text-subtle); } .variant-link { color: var(--color-primary); text-decoration: none; padding: var(--space-xs); border-radius: var(--border-radius-sm); transition: background 0.2s ease; } .variant-link:hover { background: var(--color-primary-alpha-10); } .no-variants { text-align: center; color: var(--color-text-subtle); font-style: italic; margin: 0; } .image-error { text-align: center; padding: var(--space-xl); color: var(--color-text-subtle); } .image-error__icon { font-size: 3rem; margin-bottom: var(--space-md); } .image-error h3 { margin: 0 0 var(--space-sm) 0; color: var(--color-text-primary); } .image-error p { margin: 0 0 var(--space-lg) 0; } /* Notification Styles ========================================================================== */ .notification { position: fixed; top: var(--space-lg); right: var(--space-lg); z-index: 1100; max-width: 400px; background: var(--color-surface-elevated); border-radius: var(--border-radius-lg); box-shadow: var(--shadow-lg); opacity: 0; transform: translateX(100%); transition: all 0.3s ease; } .notification--visible { opacity: 1; transform: translateX(0); } .notification--success { border-left: 4px solid var(--color-success); } .notification--error { border-left: 4px solid var(--color-danger); } .notification--info { border-left: 4px solid var(--color-primary); } .notification__content { display: flex; align-items: center; justify-content: space-between; padding: var(--space-md); } .notification__message { flex: 1; margin-right: var(--space-sm); } .notification__close { background: none; border: none; font-size: var(--font-size-lg); color: var(--color-text-subtle); cursor: pointer; padding: var(--space-xs); border-radius: var(--border-radius-sm); } .notification__close:hover { background: var(--color-surface-subtle); } /* Loading Spinner ========================================================================== */ .loading-spinner { width: 40px; height: 40px; border: 3px solid var(--color-border-subtle); border-top: 3px solid var(--color-primary); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* Modal Open State ========================================================================== */ body.modal-open { overflow: hidden; } /* Focus Styles ========================================================================== */ .image-upload-area:focus { outline: 2px solid var(--color-primary); outline-offset: 2px; } .gallery__item:focus-within { outline: 2px solid var(--color-primary); outline-offset: 2px; } /* Reduced Motion ========================================================================== */ @media (prefers-reduced-motion: reduce) { .image-modal__container, .notification, .gallery__item, .upload-area__button, .modal-btn, .action-btn { transition: none; animation: none; } .loading-spinner { animation: none; border: 3px solid var(--color-primary); } } /* Print Styles ========================================================================== */ @media print { .image-modal, .notification, .gallery__item-overlay, .upload-area__button { display: none !important; } }