@import 'tailwindcss'; @import '@immich/ui/theme/default.css'; @source "../node_modules/@immich/ui"; /* @import '/usr/ui/dist/theme/default.css'; */ @utility immich-form-input { @apply bg-gray-100 ring-1 ring-gray-200 transition outline-none focus-within:ring-1 disabled:cursor-not-allowed dark:bg-gray-800 dark:ring-neutral-900 flex w-full items-center rounded-lg disabled:bg-gray-300 disabled:text-dark dark:disabled:bg-gray-900 dark:disabled:text-gray-200 flex-1 py-2.5 text-base pl-4 pr-4; } @utility immich-form-label { @apply font-medium text-gray-500 dark:text-gray-300; } @utility immich-scrollbar { /* width */ scrollbar-width: thin; } @utility scrollbar-hidden { /* Hidden scrollbar */ /* width */ scrollbar-width: none; } @utility scrollbar-stable { scrollbar-gutter: stable both-edges; } @utility grid-auto-fit-* { grid-template-columns: repeat(auto-fit, minmax(min(calc(var(--spacing) * --value(number)), 100%), 1fr)); } @utility grid-auto-fill-* { grid-template-columns: repeat(auto-fill, minmax(min(calc(var(--spacing) * --value(number)), 100%), 1fr)); } @custom-variant dark (&:where(.dark, .dark *):not(.light)); @theme inline { --color-immich-primary: rgb(var(--immich-primary)); --color-immich-bg: rgb(var(--immich-bg)); --color-immich-fg: rgb(var(--immich-fg)); --color-immich-gray: rgb(var(--immich-gray)); --color-immich-dark-primary: rgb(var(--immich-dark-primary)); --color-immich-dark-bg: rgb(var(--immich-dark-bg)); --color-immich-dark-fg: rgb(var(--immich-dark-fg)); --color-immich-dark-gray: rgb(var(--immich-dark-gray)); } @theme { --font-sans: 'GoogleSans', sans-serif; --font-mono: 'GoogleSansCode', monospace; --spacing-18: 4.5rem; --breakpoint-tall: 800px; --breakpoint-2xl: 1535px; --breakpoint-xl: 1279px; --breakpoint-lg: 1023px; --breakpoint-md: 767px; --breakpoint-sm: 639px; --breakpoint-sidebar: 850px; } @layer base { :root { /* light */ --immich-primary: 66 80 175; --immich-bg: 255 255 255; --immich-fg: 0 0 0; /* dark */ --immich-dark-primary: 172 203 250; --immich-dark-bg: 10 10 10; --immich-dark-fg: 229 231 235; --immich-dark-gray: 33 33 33; /* transitions */ --immich-split-viewer-nav: enabled; /* view transition variables */ /* Base animation duration for standard transitions (page fades, info panel) */ --vt-duration-default: 250ms; /* Duration for hero transitions (thumbnail to full viewer) */ --vt-duration-hero: 280ms; /* Duration for next/previous photo navigation */ --vt-duration-viewer-navigation: 270ms; /* Duration for slideshow mode transitions */ --vt-duration-slideshow: 1s; /* Easing function for slide animations (ease-out) */ --vt-viewer-slide-easing: cubic-bezier(0.2, 0, 0, 1); /* How far images slide in/out during navigation (% of viewport) */ --vt-viewer-slide-distance: 15%; /* Starting opacity for fly transitions (slide+fade effect) */ --vt-viewer-opacity-start: 0.1; /* Maximum blur during fly transitions (currently disabled) */ --vt-viewer-blur-max: 0px; --vt-viewer-next-in: flyInRight; --vt-viewer-next-out: flyOutLeft; --vt-viewer-prev-in: flyInLeft; --vt-viewer-prev-out: flyOutRight; --vt-viewer-old-opacity: 1; } button:not(:disabled), [role='button']:not(:disabled) { cursor: pointer; } } @layer utilities { @font-face { font-family: 'GoogleSans'; src: url('$lib/assets/fonts/GoogleSans/GoogleSans.ttf') format('truetype-variations'); font-weight: 410 900; font-style: normal; ascent-override: 106.25%; size-adjust: 106.25%; } @font-face { font-family: 'GoogleSansCode'; src: url('$lib/assets/fonts/GoogleSansCode/GoogleSansCode.ttf') format('truetype-variations'); font-weight: 1 900; font-style: monospace; } :root { font-family: var(--font-sans); letter-spacing: 0.1px; /* Used by layouts to ensure proper spacing between navbar and content */ --navbar-height: calc(4.5rem + 4px); --navbar-height-md: calc(4.5rem + 4px - 14px); } :root.dark { color-scheme: dark; } :root:not(.dark) { color-scheme: light; } html { height: 100%; width: 100%; } html::-webkit-scrollbar { width: 8px; } /* Track */ html::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 16px; } /* Handle */ html::-webkit-scrollbar-thumb { background: rgba(85, 86, 87, 0.408); border-radius: 16px; } /* Handle on hover */ html::-webkit-scrollbar-thumb:hover { background: #4250afad; border-radius: 16px; } body { margin: 0; color: #3a3a3a; } body.asset-viewer-open { background-color: black; } input:focus-visible { outline-offset: 0px !important; outline: none !important; } .text-white-shadow { text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8); } .icon-white-drop-shadow { filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.8)); } } .maplibregl-popup { .maplibregl-popup-tip { @apply border-t-subtle! translate-y-[-1px]; } .maplibregl-popup-content { @apply bg-subtle rounded-lg; } } @layer base { ::view-transition { background: var(--color-black); animation-duration: var(--vt-duration-default); } ::view-transition-old(*), ::view-transition-new(*) { mix-blend-mode: normal; animation-duration: inherit; } ::view-transition-old(*) { animation-name: fadeOut; animation-fill-mode: forwards; } ::view-transition-new(*) { animation-name: fadeIn; animation-fill-mode: forwards; } ::view-transition-old(root) { animation: var(--vt-duration-default) 0s fadeOut forwards; } ::view-transition-new(root) { animation: var(--vt-duration-default) 0s fadeIn forwards; } html:active-view-transition-type(slideshow) { &::view-transition-old(*) { animation: var(--vt-duration-slideshow) linear crossfadeOut forwards; } &::view-transition-new(*) { animation: var(--vt-duration-slideshow) linear crossfadeIn forwards; } &::view-transition-image-pair(*) { isolation: auto; } } html:active-view-transition-type(viewer-nav) { &::view-transition-old(root) { animation: var(--vt-duration-hero) 0s fadeOut forwards; } &::view-transition-new(root) { animation: var(--vt-duration-hero) 0s fadeIn forwards; } } ::view-transition-image-pair(info) { isolation: auto; } ::view-transition-old(info) { animation: var(--vt-duration-default) 0s panelSlideOutRight forwards; } ::view-transition-new(info) { animation: var(--vt-duration-default) 0s panelSlideInRight forwards; } ::view-transition-group(detail-panel) { z-index: 1; } ::view-transition-old(detail-panel), ::view-transition-new(detail-panel) { animation: none; } ::view-transition-group(letterbox-left), ::view-transition-group(letterbox-right), ::view-transition-group(letterbox-top), ::view-transition-group(letterbox-bottom) { animation-duration: var(--vt-duration-viewer-navigation); animation-timing-function: var(--vt-viewer-slide-easing); z-index: 4; } ::view-transition-image-pair(letterbox-left), ::view-transition-image-pair(letterbox-right), ::view-transition-image-pair(letterbox-top), ::view-transition-image-pair(letterbox-bottom) { isolation: auto; } ::view-transition-old(letterbox-left), ::view-transition-old(letterbox-right), ::view-transition-old(letterbox-top), ::view-transition-old(letterbox-bottom), ::view-transition-new(letterbox-left), ::view-transition-new(letterbox-right), ::view-transition-new(letterbox-top), ::view-transition-new(letterbox-bottom) { animation: none; width: 100%; height: 100%; object-fit: fill; background-color: var(--color-black); } ::view-transition-group(exclude-leftbutton), ::view-transition-group(exclude-rightbutton), ::view-transition-group(exclude) { animation: none; z-index: 5; } ::view-transition-old(exclude-leftbutton), ::view-transition-old(exclude-rightbutton), ::view-transition-old(exclude) { visibility: hidden; } ::view-transition-new(exclude-leftbutton), ::view-transition-new(exclude-rightbutton), ::view-transition-new(exclude) { animation: none; z-index: 5; } ::view-transition-group(hero) { animation-duration: var(--vt-duration-hero); animation-timing-function: cubic-bezier(0.2, 0, 0, 1); } ::view-transition-old(hero), ::view-transition-new(hero) { animation: none; align-content: center; } ::view-transition-old(next), ::view-transition-old(next-old), ::view-transition-new(next), ::view-transition-new(next-new), ::view-transition-old(previous), ::view-transition-old(previous-old), ::view-transition-new(previous), ::view-transition-new(previous-new) { animation-duration: var(--vt-duration-viewer-navigation); animation-timing-function: var(--vt-viewer-slide-easing); animation-fill-mode: forwards; } ::view-transition-old(next), ::view-transition-old(next-old), ::view-transition-old(previous), ::view-transition-old(previous-old) { opacity: var(--vt-viewer-old-opacity); } ::view-transition-old(next), ::view-transition-old(next-old) { animation-name: var(--vt-viewer-next-out); } ::view-transition-new(next), ::view-transition-new(next-new) { animation-name: var(--vt-viewer-next-in); } ::view-transition-old(previous), ::view-transition-old(previous-old) { animation-name: var(--vt-viewer-prev-out); } ::view-transition-new(previous), ::view-transition-new(previous-new) { animation-name: var(--vt-viewer-prev-in); } ::view-transition-old(next-old), ::view-transition-new(next-new), ::view-transition-old(previous-old), ::view-transition-new(previous-new) { overflow: hidden; } ::view-transition-old(previous-old) { z-index: -1; } @keyframes flyInLeft { from { transform: translateX(calc(-1 * var(--vt-viewer-slide-distance))); opacity: var(--vt-viewer-opacity-start); filter: blur(var(--vt-viewer-blur-max)); } to { opacity: 1; filter: blur(0); } } @keyframes flyOutLeft { from { opacity: 1; filter: blur(0); } to { transform: translateX(calc(-1 * var(--vt-viewer-slide-distance))); opacity: var(--vt-viewer-opacity-start); filter: blur(var(--vt-viewer-blur-max)); } } @keyframes flyInRight { from { transform: translateX(var(--vt-viewer-slide-distance)); opacity: var(--vt-viewer-opacity-start); filter: blur(var(--vt-viewer-blur-max)); } to { opacity: 1; filter: blur(0); } } @keyframes flyOutRight { from { opacity: 1; filter: blur(0); } to { transform: translateX(var(--vt-viewer-slide-distance)); opacity: var(--vt-viewer-opacity-start); filter: blur(var(--vt-viewer-blur-max)); } } @keyframes panelSlideInRight { from { transform: translateX(100%); } to { transform: translateX(0); } } @keyframes panelSlideOutRight { from { transform: translateX(0); } to { transform: translateX(100%); } } /* cubic fade curves so combined opacity stays close to 1.0 during crossfade */ @keyframes fadeIn { from { opacity: 0; } 50% { opacity: 0.85; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } 50% { opacity: 0.85; } to { opacity: 0; } } @keyframes crossfadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes crossfadeOut { from { opacity: 1; } to { opacity: 0; } } @media (prefers-reduced-motion: reduce) { ::view-transition-group(hero) { animation-name: none; } ::view-transition-old(hero) { animation: none; display: none; } ::view-transition-new(hero) { animation: none; } html:active-view-transition-type(viewer) { &::view-transition-old(hero) { animation: none; display: none; } &::view-transition-new(hero) { animation: var(--vt-duration-default) 0s fadeIn forwards; } } html:active-view-transition-type(timeline) { &::view-transition-old(hero) { animation: var(--vt-duration-default) 0s fadeOut forwards; } &::view-transition-new(hero) { animation: var(--vt-duration-default) 0s fadeIn forwards; } } ::view-transition-group(letterbox-left), ::view-transition-group(letterbox-right), ::view-transition-group(letterbox-top), ::view-transition-group(letterbox-bottom) { z-index: 100; } ::view-transition-old(letterbox-left), ::view-transition-old(letterbox-right), ::view-transition-old(letterbox-top), ::view-transition-old(letterbox-bottom), ::view-transition-new(letterbox-left), ::view-transition-new(letterbox-right), ::view-transition-new(letterbox-top), ::view-transition-new(letterbox-bottom) { background-color: transparent; } ::view-transition-group(previous), ::view-transition-group(previous-old), ::view-transition-group(next), ::view-transition-group(next-old) { width: 100% !important; height: 100% !important; transform: none !important; } ::view-transition-old(previous), ::view-transition-old(previous-old), ::view-transition-old(next), ::view-transition-old(next-old) { animation: var(--vt-duration-viewer-navigation) fadeOut forwards; transform-origin: center; height: 100%; width: 100%; object-fit: contain; overflow: hidden; } ::view-transition-new(previous), ::view-transition-new(previous-new), ::view-transition-new(next), ::view-transition-new(next-new) { animation: var(--vt-duration-viewer-navigation) fadeIn forwards; transform-origin: center; height: 100%; width: 100%; object-fit: contain; } } }