diff --git a/gallery/__init__.py b/onlylegs/__init__.py similarity index 94% rename from gallery/__init__.py rename to onlylegs/__init__.py index 42ff00b..66c34d0 100644 --- a/gallery/__init__.py +++ b/onlylegs/__init__.py @@ -16,11 +16,11 @@ from flask import Flask, render_template, abort from werkzeug.exceptions import HTTPException from werkzeug.security import generate_password_hash -from gallery.extensions import db, migrate, login_manager, assets, compress, cache -from gallery.views import index, image, group, settings, profile -from gallery.models import User -from gallery import api -from gallery import auth +from onlylegs.extensions import db, migrate, login_manager, assets, compress, cache +from onlylegs.views import index, image, group, settings, profile +from onlylegs.models import User +from onlylegs import api +from onlylegs import auth INSTACE_DIR = os.path.join(platformdirs.user_config_dir("onlylegs"), "instance") diff --git a/gallery/api.py b/onlylegs/api.py similarity index 96% rename from gallery/api.py rename to onlylegs/api.py index 379e5b1..3ddfc3b 100644 --- a/gallery/api.py +++ b/onlylegs/api.py @@ -13,10 +13,10 @@ from flask_login import login_required, current_user from colorthief import ColorThief -from gallery.extensions import db -from gallery.models import Post, Group, GroupJunction -from gallery.utils import metadata as mt -from gallery.utils.generate_image import generate_thumbnail +from onlylegs.extensions import db +from onlylegs.models import Post, Group, GroupJunction +from onlylegs.utils import metadata as mt +from onlylegs.utils.generate_image import generate_thumbnail blueprint = Blueprint("api", __name__, url_prefix="/api") diff --git a/gallery/auth.py b/onlylegs/auth.py similarity index 97% rename from gallery/auth.py rename to onlylegs/auth.py index 0973384..6b5884f 100644 --- a/gallery/auth.py +++ b/onlylegs/auth.py @@ -10,8 +10,8 @@ from werkzeug.security import check_password_hash, generate_password_hash from flask_login import login_user, logout_user, login_required -from gallery.extensions import db -from gallery.models import User +from onlylegs.extensions import db +from onlylegs.models import User blueprint = Blueprint("auth", __name__, url_prefix="/auth") diff --git a/gallery/config.py b/onlylegs/config.py similarity index 100% rename from gallery/config.py rename to onlylegs/config.py diff --git a/gallery/extensions.py b/onlylegs/extensions.py similarity index 100% rename from gallery/extensions.py rename to onlylegs/extensions.py diff --git a/gallery/langs/gb.json b/onlylegs/langs/gb.json similarity index 100% rename from gallery/langs/gb.json rename to onlylegs/langs/gb.json diff --git a/gallery/models.py b/onlylegs/models.py similarity index 98% rename from gallery/models.py rename to onlylegs/models.py index 3958f9c..ace0b67 100644 --- a/gallery/models.py +++ b/onlylegs/models.py @@ -3,7 +3,7 @@ OnlyLegs - Database models and ions for SQLAlchemy """ from uuid import uuid4 from flask_login import UserMixin -from .extensions import db +from onlylegs.extensions import db class GroupJunction(db.Model): # pylint: disable=too-few-public-methods, C0103 diff --git a/onlylegs/static/.webassets-cache/048ab2d0afc0753b21fd37760d6336a9 b/onlylegs/static/.webassets-cache/048ab2d0afc0753b21fd37760d6336a9 new file mode 100644 index 0000000..0872bc8 Binary files /dev/null and b/onlylegs/static/.webassets-cache/048ab2d0afc0753b21fd37760d6336a9 differ diff --git a/onlylegs/static/.webassets-cache/245b356d139a542e35f66e3a24abcd83 b/onlylegs/static/.webassets-cache/245b356d139a542e35f66e3a24abcd83 new file mode 100644 index 0000000..7837913 Binary files /dev/null and b/onlylegs/static/.webassets-cache/245b356d139a542e35f66e3a24abcd83 differ diff --git a/onlylegs/static/.webassets-cache/2703fbc99768caa84c204331ae2d614f b/onlylegs/static/.webassets-cache/2703fbc99768caa84c204331ae2d614f new file mode 100644 index 0000000..508efbc Binary files /dev/null and b/onlylegs/static/.webassets-cache/2703fbc99768caa84c204331ae2d614f differ diff --git a/onlylegs/static/.webassets-cache/3f5dd8900ac3b9691849ca7ae7dfb270 b/onlylegs/static/.webassets-cache/3f5dd8900ac3b9691849ca7ae7dfb270 new file mode 100644 index 0000000..2dd0d1f Binary files /dev/null and b/onlylegs/static/.webassets-cache/3f5dd8900ac3b9691849ca7ae7dfb270 differ diff --git a/onlylegs/static/.webassets-cache/4fc49eeb19703df20e8b664cbd5024ff b/onlylegs/static/.webassets-cache/4fc49eeb19703df20e8b664cbd5024ff new file mode 100644 index 0000000..62aea8f Binary files /dev/null and b/onlylegs/static/.webassets-cache/4fc49eeb19703df20e8b664cbd5024ff differ diff --git a/onlylegs/static/.webassets-cache/616146e95f4b4f878d3737cf9fd1ea3c b/onlylegs/static/.webassets-cache/616146e95f4b4f878d3737cf9fd1ea3c new file mode 100644 index 0000000..ba54b4b Binary files /dev/null and b/onlylegs/static/.webassets-cache/616146e95f4b4f878d3737cf9fd1ea3c differ diff --git a/onlylegs/static/.webassets-cache/695be00eadf74d7648f7b55cf5b436ec b/onlylegs/static/.webassets-cache/695be00eadf74d7648f7b55cf5b436ec new file mode 100644 index 0000000..0a63a9c Binary files /dev/null and b/onlylegs/static/.webassets-cache/695be00eadf74d7648f7b55cf5b436ec differ diff --git a/onlylegs/static/.webassets-cache/8af5c2621194ec42b82ffd3ae7011057 b/onlylegs/static/.webassets-cache/8af5c2621194ec42b82ffd3ae7011057 new file mode 100644 index 0000000..c1f3686 Binary files /dev/null and b/onlylegs/static/.webassets-cache/8af5c2621194ec42b82ffd3ae7011057 differ diff --git a/onlylegs/static/.webassets-cache/8d5c5be1180b0291e9379c042289e36c b/onlylegs/static/.webassets-cache/8d5c5be1180b0291e9379c042289e36c new file mode 100644 index 0000000..751fcc9 Binary files /dev/null and b/onlylegs/static/.webassets-cache/8d5c5be1180b0291e9379c042289e36c differ diff --git a/onlylegs/static/.webassets-cache/9ba12571fa602e397529552be4012a96 b/onlylegs/static/.webassets-cache/9ba12571fa602e397529552be4012a96 new file mode 100644 index 0000000..95e2e28 Binary files /dev/null and b/onlylegs/static/.webassets-cache/9ba12571fa602e397529552be4012a96 differ diff --git a/onlylegs/static/.webassets-cache/f74d4479d7a0247efebd02e2d7c007bd b/onlylegs/static/.webassets-cache/f74d4479d7a0247efebd02e2d7c007bd new file mode 100644 index 0000000..4954e4d Binary files /dev/null and b/onlylegs/static/.webassets-cache/f74d4479d7a0247efebd02e2d7c007bd differ diff --git a/gallery/static/error.png b/onlylegs/static/error.png similarity index 100% rename from gallery/static/error.png rename to onlylegs/static/error.png diff --git a/gallery/static/fonts/Rubik.ttf b/onlylegs/static/fonts/Rubik.ttf similarity index 100% rename from gallery/static/fonts/Rubik.ttf rename to onlylegs/static/fonts/Rubik.ttf diff --git a/gallery/static/fonts/font.css b/onlylegs/static/fonts/font.css similarity index 100% rename from gallery/static/fonts/font.css rename to onlylegs/static/fonts/font.css diff --git a/onlylegs/static/gen/js.js b/onlylegs/static/gen/js.js new file mode 100644 index 0000000..6e93390 --- /dev/null +++ b/onlylegs/static/gen/js.js @@ -0,0 +1,45 @@ +function imgFade(obj,time=250){obj.style.transition=`opacity ${time}ms`;obj.style.opacity=1;} +function loadOnView(){const lazyLoad=document.querySelectorAll('#lazy-load');const webpSupport=checkWebpSupport();for(let i=0;i0){if(!image.src&&webpSupport){image.src=image.getAttribute('data-src')+'&e=webp'}else if(!image.src){image.src=image.getAttribute('data-src')}}}} +window.onload=function(){loadOnView();let times=document.querySelectorAll('.time');for(let i=0;i300||document.documentElement.scrollTop>20){topOfPage.classList.add('show');}else{topOfPage.classList.remove('show');} +topOfPage.onclick=function(){document.body.scrollTop=0;document.documentElement.scrollTop=0;} +let infoButton=document.querySelector('.info-button');if(infoButton){if(document.body.scrollTop>300||document.documentElement.scrollTop>20){infoButton.classList.remove('show');}else{infoButton.classList.add('show');} +infoButton.onclick=function(){popUpShow('OnlyLegs','V23.04.10 '+ +'using Phosphoricons and Flask.'+ +'
Made by Fluffy and others with ❤️');}}};window.onscroll=function(){loadOnView();let topOfPage=document.querySelector('.top-of-page');if(document.body.scrollTop>300||document.documentElement.scrollTop>20){topOfPage.classList.add('show');}else{topOfPage.classList.remove('show');} +let infoButton=document.querySelector('.info-button');if(infoButton){if(document.body.scrollTop>300||document.documentElement.scrollTop>20){infoButton.classList.remove('show');}else{infoButton.classList.add('show');}}};window.onresize=function(){loadOnView();};function showLogin(){cancelBtn=document.createElement('button');cancelBtn.classList.add('btn-block');cancelBtn.innerHTML='nuuuuuuuu';cancelBtn.onclick=popupDissmiss;loginBtn=document.createElement('button');loginBtn.classList.add('btn-block');loginBtn.classList.add('primary');loginBtn.innerHTML='Login';loginBtn.type='submit';loginBtn.setAttribute('form','loginForm');loginForm=document.createElement('form');loginForm.id='loginForm';loginForm.setAttribute('onsubmit','return login(event);');usernameInput=document.createElement('input');usernameInput.classList.add('input-block');usernameInput.type='text';usernameInput.placeholder='Namey';usernameInput.id='username';passwordInput=document.createElement('input');passwordInput.classList.add('input-block');passwordInput.type='password';passwordInput.placeholder='Passywassy';passwordInput.id='password';rememberMeSpan=document.createElement('span');rememberMeSpan.classList.add('input-checkbox');rememberMeInput=document.createElement('input');rememberMeInput.type='checkbox';rememberMeInput.id='remember-me';rememberMeLabel=document.createElement('label');rememberMeLabel.innerHTML='No forgetty me pls';rememberMeLabel.setAttribute('for','remember-me');rememberMeSpan.appendChild(rememberMeInput);rememberMeSpan.appendChild(rememberMeLabel);loginForm.appendChild(usernameInput);loginForm.appendChild(passwordInput);loginForm.appendChild(rememberMeSpan);popUpShow('Login!','Need an account? Register!',loginForm,[cancelBtn,loginBtn]);} +function login(event){event.preventDefault();let formUsername=document.querySelector("#username").value;let formPassword=document.querySelector("#password").value;let formRememberMe=document.querySelector("#remember-me").checked;if(formUsername===""||formPassword===""){addNotification("Please fill in all fields!!!!",3);return;} +const formData=new FormData();formData.append("username",formUsername);formData.append("password",formPassword);formData.append("remember-me",formRememberMe);fetch('/auth/login',{method:'POST',body:formData}).then(response=>{if(response.ok){location.reload();}else{if(response.status===403){addNotification('None but devils play past here... Wrong information',2);}else if(response.status===500){addNotification('Server exploded, F\'s in chat',2);}else{addNotification('Error logging in, blame someone',2);}}}).catch(error=>{addNotification('Error logging in, blame someone',2);});} +function showRegister(){cancelBtn=document.createElement('button');cancelBtn.classList.add('btn-block');cancelBtn.innerHTML='nuuuuuuuu';cancelBtn.onclick=popupDissmiss;registerBtn=document.createElement('button');registerBtn.classList.add('btn-block');registerBtn.classList.add('primary');registerBtn.innerHTML='Register';registerBtn.type='submit';registerBtn.setAttribute('form','registerForm');registerForm=document.createElement('form');registerForm.id='registerForm';registerForm.setAttribute('onsubmit','return register(event);');usernameInput=document.createElement('input');usernameInput.classList.add('input-block');usernameInput.type='text';usernameInput.placeholder='Namey';usernameInput.id='username';emailInput=document.createElement('input');emailInput.classList.add('input-block');emailInput.type='text';emailInput.placeholder='E mail!';emailInput.id='email';passwordInput=document.createElement('input');passwordInput.classList.add('input-block');passwordInput.type='password';passwordInput.placeholder='Passywassy';passwordInput.id='password';passwordInputRepeat=document.createElement('input');passwordInputRepeat.classList.add('input-block');passwordInputRepeat.type='password';passwordInputRepeat.placeholder='Passywassy again!';passwordInputRepeat.id='password-repeat';registerForm.appendChild(usernameInput);registerForm.appendChild(emailInput);registerForm.appendChild(passwordInput);registerForm.appendChild(passwordInputRepeat);popUpShow('Who are you?','Already have an account? Login!',registerForm,[cancelBtn,registerBtn]);} +function register(event){event.preventDefault();let formUsername=document.querySelector("#username").value;let formEmail=document.querySelector("#email").value;let formPassword=document.querySelector("#password").value;let formPasswordRepeat=document.querySelector("#password-repeat").value;if(formUsername===""||formEmail===""||formPassword===""||formPasswordRepeat===""){addNotification("Please fill in all fields!!!!",3);return;} +const formData=new FormData();formData.append("username",formUsername);formData.append("email",formEmail);formData.append("password",formPassword);formData.append("password-repeat",formPasswordRepeat);fetch('/auth/register',{method:'POST',body:formData}).then(response=>{if(response.ok){addNotification('Registered successfully! Now please login to continue',1);showLogin();}else{if(response.status===400){response.json().then(data=>{for(let i=0;i{addNotification('Error logging in, blame someone',2);});} +function addNotification(notificationText,notificationLevel){const notificationContainer=document.querySelector('.notifications');const successIcon='';const criticalIcon='';const warningIcon='';const infoIcon='';const notification=document.createElement('div');notification.classList.add('sniffle__notification');notification.onclick=function(){if(notification){notification.classList.add('hide');setTimeout(function(){notificationContainer.removeChild(notification);},500);}};const iconElement=document.createElement('span');iconElement.classList.add('sniffle__notification-icon');notification.appendChild(iconElement);if(notificationLevel===1){notification.classList.add('success');iconElement.innerHTML=successIcon;}else if(notificationLevel===2){notification.classList.add('critical');iconElement.innerHTML=criticalIcon;}else if(notificationLevel===3){notification.classList.add('warning');iconElement.innerHTML=warningIcon;}else{notification.classList.add('info');iconElement.innerHTML=infoIcon;} +const description=document.createElement('span');description.classList.add('sniffle__notification-text');description.innerHTML=notificationText;notification.appendChild(description);notificationContainer.appendChild(notification);setTimeout(function(){notification.classList.add('show');},5);setTimeout(function(){if(notification){notification.classList.add('hide');setTimeout(function(){notificationContainer.removeChild(notification);},500);}},5000);} +function popUpShow(titleText,subtitleText,bodyContent=null,userActions=null){const popupSelector=document.querySelector('.pop-up');const headerSelector=document.querySelector('.pop-up-header');const actionsSelector=document.querySelector('.pop-up-controlls');headerSelector.innerHTML='';actionsSelector.innerHTML='';const titleElement=document.createElement('h2');titleElement.innerHTML=titleText;headerSelector.appendChild(titleElement);const subtitleElement=document.createElement('p');subtitleElement.innerHTML=subtitleText;headerSelector.appendChild(subtitleElement);if(bodyContent){headerSelector.appendChild(bodyContent);} +if(userActions){for(let i=0;iClose';} +document.querySelector("html").style.overflow="hidden";popupSelector.style.display='block';setTimeout(function(){popupSelector.classList.add('active')},5);} +function popupDissmiss(){const popupSelector=document.querySelector('.pop-up');document.querySelector("html").style.overflow="auto";popupSelector.classList.remove('active');setTimeout(function(){popupSelector.style.display='none';},200);} +window.addEventListener("dragover",(event)=>{event.preventDefault();},false);window.addEventListener("drop",(event)=>{event.preventDefault();},false);function openUploadTab(){let uploadTab=document.querySelector(".upload-panel");document.querySelector("html").style.overflow="hidden";uploadTab.style.display="block";setTimeout(function(){uploadTab.classList.add("open");},5);} +function closeUploadTab(){let uploadTab=document.querySelector(".upload-panel");let uploadTabContainer=document.querySelector(".upload-panel .container");document.querySelector("html").style.overflow="auto";uploadTab.classList.remove("open");setTimeout(function(){uploadTab.style.display="none";uploadTabContainer.style.transform="";uploadTab.dataset.lastY=0;},250);} +function toggleUploadTab(){let uploadTab=document.querySelector(".upload-panel");if(uploadTab.classList.contains("open")){closeUploadTab();}else{openUploadTab();}} +function tabDragStart(event){event.preventDefault();let uploadTab=document.querySelector(".upload-panel .container");let offset=uploadTab.getBoundingClientRect().y;uploadTab.classList.add("dragging");document.addEventListener('touchmove',event=>{if(uploadTab.classList.contains("dragging")){if(event.touches[0].clientY-offset>=0){uploadTab.dataset.lastY=event.touches[0].clientY;}else{uploadTab.dataset.lastY=offset;} +uploadTab.style.transform=`translateY(${uploadTab.dataset.lastY-offset}px)`;}});} +function tabDragStopped(event){event.preventDefault();let uploadTab=document.querySelector(".upload-panel .container");uploadTab.classList.remove("dragging");if(uploadTab.dataset.lastY>(screen.height*0.3)){closeUploadTab();}else{uploadTab.style.transition="transform 0.25s cubic-bezier(0.76, 0, 0.17, 1)";uploadTab.style.transform="translateY(0px)";setTimeout(function(){uploadTab.style.transition="";},250);}} +function fileActivate(event){event.preventDefault() +let fileDrop=document.querySelector('.fileDrop-block');let fileDropTitle=fileDrop.querySelector('.status');fileDrop.classList.remove('error');fileDrop.classList.add('edging');fileDropTitle.innerHTML='Drop to upload!';} +function fileDefault(){let fileDrop=document.querySelector('.fileDrop-block');let fileDropTitle=fileDrop.querySelector('.status');fileDrop.classList.remove('error');fileDrop.classList.remove('edging');fileDropTitle.innerHTML='Choose or Drop file';} +function fileDropHandle(event){event.preventDefault() +let fileDrop=document.querySelector('.fileDrop-block');let fileUpload=fileDrop.querySelector('#file');fileUpload.files=event.dataTransfer.files;fileDefault();fileChanged();} +function fileChanged(){let dropBlock=document.querySelector('.fileDrop-block');let dropBlockStatus=dropBlock.querySelector('.status');let dropBlockInput=dropBlock.querySelector('#file');if(dropBlockInput.value!==""){dropBlock.classList.add('active');dropBlockStatus.innerHTML=dropBlockInput.files[0].name;}else{fileDefault();}} +function clearUpload(){let fileDrop=document.querySelector('#uploadForm');let fileUpload=fileDrop.querySelector('#file');let fileAlt=fileDrop.querySelector('#alt');let fileDescription=fileDrop.querySelector('#description');let fileTags=fileDrop.querySelector('#tags');fileUpload.value="";fileAlt.value="";fileDescription.value="";fileTags.value="";} +document.addEventListener('DOMContentLoaded',()=>{let uploadTab=document.querySelector(".upload-panel");if(!uploadTab){return;} +let uploadTabDrag=uploadTab.querySelector("#dragIndicator");let uploadForm=uploadTab.querySelector('#uploadForm');let fileDrop=uploadForm.querySelector('.fileDrop-block');let fileDropTitle=fileDrop.querySelector('.status');let fileUpload=fileDrop.querySelector('#file');let fileAlt=uploadForm.querySelector('#alt');let fileDescription=uploadForm.querySelector('#description');let fileTags=uploadForm.querySelector('#tags');clearUpload();fileDefault();uploadTabDrag.addEventListener('touchstart',tabDragStart,false);uploadTabDrag.addEventListener('touchend',tabDragStopped,false);fileDrop.addEventListener('dragover',fileActivate,false);fileDrop.addEventListener('dragenter',fileActivate,false);fileDrop.addEventListener('dragleave',fileDefault,false);fileDrop.addEventListener('drop',fileDropHandle,false);fileUpload.addEventListener('change',fileChanged,false);fileUpload.addEventListener('click',fileDefault,false);uploadForm.addEventListener('submit',(event)=>{event.preventDefault() +if(fileUpload.value===""){fileDrop.classList.add('error');fileDropTitle.innerHTML='No file selected!';return;} +let formData=new FormData();formData.append("file",fileUpload.files[0]);formData.append("alt",fileAlt.value);formData.append("description",fileDescription.value);formData.append("tags",fileTags.value);fetch('/api/upload',{method:'POST',body:formData}) +.then(data=>{addNotification("Image uploaded successfully",1);}).catch(error=>{switch(response.status){case 500:addNotification("Server exploded, F's in chat",2) +break;case 400:case 404:addNotification("Error uploading. Blame yourself",2) +break;case 403:addNotification("None but devils play past here...",2) +break;case 413:addNotification("File too large!!!!!!",2);break;default:addNotification("Error uploading file, blame someone",2) +break;}});clearUpload();fileDrop.classList.remove('active');fileDropTitle.innerHTML='Choose or Drop file';});});function checkWebpSupport(){let webpSupport=false;try{webpSupport=document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp')===0;}catch(e){webpSupport=false;} +return webpSupport;} \ No newline at end of file diff --git a/onlylegs/static/gen/styles.css b/onlylegs/static/gen/styles.css new file mode 100644 index 0000000..888b0a9 --- /dev/null +++ b/onlylegs/static/gen/styles.css @@ -0,0 +1 @@ +@keyframes imgLoading{0%{background-position:-468px 0}100%{background-position:468px 0}}@keyframes uploadingLoop{0%{left:-100%}100%{left:100%}}:root{--bg-dim:16,16,16;--bg-bright:232,227,227;--bg-100:21,21,21;--bg-200:26.1,26.1,26.1;--bg-300:31.2,31.2,31.2;--bg-400:36.3,36.3,36.3;--bg-500:41.4,41.4,41.4;--bg-600:46.5,46.5,46.5;--fg-dim:102,102,102;--fg-white:232,227,227;--fg-black:16,16,16;--black:21,21,21;--white:232,227,227;--red:182,100,103;--orange:217,140,95;--yellow:217,188,140;--green:140,151,125;--blue:141,163,185;--purple:169,136,176;--primary:var(--green);--warning:var(--orange);--critical:var(--red);--success:var(--green);--info:var(--blue);--rad:6px;--rad-inner:calc(var(--rad) / 2);--animation-smooth:cubic-bezier(0.76,0,0.17,1);--animation-bounce:cubic-bezier(.68,-0.55,.27,1.55);--breakpoint:800px}@keyframes imgLoading{0%{background-position:-468px 0}100%{background-position:468px 0}}@keyframes uploadingLoop{0%{left:-100%}100%{left:100%}}@keyframes notificationTimeout{0%{left:-100%;height:3px}90%{left:0;height:3px}95%{left:0;height:0}100%{left:0;height:0}}.notifications{margin:0;padding:0;width:450px;height:auto;position:fixed;top:.3rem;right:.3rem;display:flex;flex-direction:column;z-index:621}.sniffle__notification{margin:0 0 .3rem 0;padding:0;width:450px;height:auto;max-height:100px;display:flex;flex-direction:row;position:relative;background-color:RGB(var(--bg-300));border-radius:var(--rad-inner);color:RGB(var(--fg-white));opacity:0;transform:scale(0.8);box-sizing:border-box;overflow:hidden;transition:all .25s ease-in-out,opacity .2s ease-in-out,transform .2s cubic-bezier(0.68,-0.55,0.27,1.55)}.sniffle__notification::after{content:"";width:100%;height:3px;position:absolute;bottom:0;left:0;background-color:RGB(var(--fg-white));z-index:+2;animation:notificationTimeout 5.1s linear}.sniffle__notification.success{color:RGB(var(--success))}.sniffle__notification.success::after{background-color:RGB(var(--success))}.sniffle__notification.warning{color:RGB(var(--warning))}.sniffle__notification.warning::after{background-color:RGB(var(--warning))}.sniffle__notification.critical{color:RGB(var(--critical))}.sniffle__notification.critical::after{background-color:RGB(var(--critical))}.sniffle__notification.info{color:RGB(var(--info))}.sniffle__notification.info::after{background-color:RGB(var(--info))}.sniffle__notification.show{opacity:1;transform:scale(1)}.sniffle__notification.hide{margin:0;max-height:0;opacity:0;transform:translateX(100%);transition:all .4s ease-in-out,max-height .2s ease-in-out}.sniffle__notification-icon{margin:0;padding:1rem;width:auto;height:auto;display:flex;justify-content:center;align-items:center;background-color:RGB(var(--bg-200))}.sniffle__notification-icon svg{width:1.25rem;height:1.25rem}.sniffle__notification-text{margin:0;padding:1rem;width:auto;height:auto;display:flex;flex-direction:column;justify-self:center;align-self:center;font-size:1rem;font-weight:600;line-height:1;text-align:left}@media(max-width:800px){.notifications{width:calc(100vw - .6rem);height:auto}.sniffle__notification{width:100%}.sniffle__notification.hide{opacity:0;transform:translateY(-5rem)}.sniffle__notification-time{width:100%}}.pop-up{width:100%;height:100vh;position:fixed;inset:0;display:none;background-color:rgba(var(--bg-dim),0.8);opacity:0;z-index:101;transition:opacity .2s ease}.pop-up .pop-up__click-off{width:100%;height:100vh;position:absolute;top:0;left:0;z-index:+1}.pop-up .pop-up-wrapper{margin:0;padding:0;width:621px;height:auto;position:absolute;bottom:50%;left:50%;transform:translate(-50%,50%) scale(0.8);display:flex;flex-direction:column;background-color:RGB(var(--bg-200));border-radius:var(--rad);overflow:hidden;z-index:+2;transition:transform .2s var(--animation-smooth)}.pop-up .pop-up-header{margin:0;padding:1rem;width:100%;height:auto;display:flex;flex-direction:column;gap:.5rem;overflow-y:auto;overflow-x:hidden;text-size-adjust:auto;text-overflow:ellipsis}.pop-up .pop-up-header h2,.pop-up .pop-up-header h3{margin:0;width:100%;position:sticky;top:0;font-size:1.5rem;font-weight:700;text-align:left;color:RGB(var(--fg-white))}.pop-up .pop-up-header p{margin:0;width:100%;font-size:1rem;font-weight:400;text-align:left;color:RGB(var(--fg-white))}.pop-up .pop-up-header p svg{width:1rem;height:1rem;display:inline-block;vertical-align:middle}.pop-up .pop-up-header a,.pop-up .pop-up-header .link{color:RGB(var(--primary));cursor:pointer;text-decoration:none}.pop-up .pop-up-header a:hover,.pop-up .pop-up-header .link:hover{text-decoration:underline}.pop-up .pop-up-header img{margin:auto;padding:0;width:auto;height:auto;max-width:100%;max-height:40vh;border-radius:var(--rad-inner)}.pop-up .pop-up-header form{margin:0;padding:0;width:100%;height:auto;display:flex;flex-direction:column;gap:.5rem;justify-content:center}.pop-up .pop-up-controlls{margin:0;padding:.25rem;width:100%;height:auto;display:flex;flex-direction:row;justify-content:flex-end;gap:.25rem;background-color:RGB(var(--bg-100))}.pop-up.active{opacity:1}.pop-up.active .pop-up-wrapper{transform:translate(-50%,50%) scale(1)}@media(max-width:800px){.pop-up .pop-up-wrapper{width:calc(100% - .75rem);max-height:95vh}.pop-up .pop-up-content{max-height:100%}.pop-up .pop-up-content img{max-height:50vh}.pop-up .pop-up-controlls button{width:100%}.pop-up.active{opacity:1}}.upload-panel{position:fixed;left:3.5rem;bottom:0;display:none;width:calc(100% - 3.5rem);height:100vh;background-color:transparent;color:RGB(var(--fg-white));overflow:hidden;z-index:68;transition:background-color .25s cubic-bezier(0.76,0,0.17,1)}.upload-panel h3{margin:0;padding:0;font-size:1.5rem;font-weight:700}.upload-panel p{margin:0;padding:0;font-size:1rem;font-weight:400}.upload-panel form{margin:0;padding:0;width:100%;display:flex;flex-direction:column;align-items:center;gap:.5rem}.upload-panel form input,.upload-panel form button{width:100%}.upload-panel .click-off{position:absolute;top:0;left:0;width:100%;height:100%;z-index:+1}.upload-panel .container{padding:1rem;position:absolute;bottom:0;left:-27rem;width:27rem;height:100%;display:flex;flex-direction:column;gap:1rem;background-color:RGB(var(--bg-200));z-index:+2;transition:left .25s cubic-bezier(0.76,0,0.17,1),bottom .25s cubic-bezier(0.76,0,0.17,1)}.upload-panel .container #dragIndicator{display:none;position:absolute;top:0;left:0;width:100%;height:5rem;z-index:+1}.upload-panel .container #dragIndicator::after{content:'';width:8rem;height:3px;position:absolute;top:.5rem;left:50%;transform:translate(-50%,-50%);background-color:RGB(var(--bg-400));border-radius:var(--rad-inner)}.upload-panel .upload-jobs{display:flex;flex-direction:column;gap:.5rem;border-radius:var(--rad);overflow-y:auto}.upload-panel .upload-jobs .job{width:100%;height:5rem;min-height:5rem;position:relative;display:flex;align-items:center;gap:.5rem;background-color:RGB(var(--bg-200));border-radius:var(--rad);overflow:hidden}.upload-panel .upload-jobs .job img{position:absolute;top:0;left:0;width:100%;height:5rem;object-fit:cover}.upload-panel .upload-jobs .job .img-filter{position:absolute;top:0;left:0;width:100%;height:100%;background-image:linear-gradient(to right,RGB(var(--bg-100)),transparent)}.upload-panel .upload-jobs .job .job__status{margin:0;padding:0;position:absolute;top:.5rem;left:.5rem;font-size:1rem;font-weight:600;color:RGB(var(--fg-white));z-index:+3;transition:color .25s cubic-bezier(0.76,0,0.17,1)}.upload-panel .upload-jobs .job .progress{width:100%;height:var(--rad-inner);position:absolute;bottom:0;left:-100%;background-color:RGB(var(--primary));animation:uploadingLoop 1s cubic-bezier(0.76,0,0.17,1) infinite;z-index:+5;transition:left 1s cubic-bezier(0.76,0,0.17,1)}.upload-panel .upload-jobs .job.critical .job__status,.upload-panel .upload-jobs .job.critical .progress{color:RGB(var(--critical))}.upload-panel .upload-jobs .job.success .job__status{color:RGB(var(--success))}.upload-panel .upload-jobs .job.success .progress{height:0;animation:none}.upload-panel .upload-jobs .job.warning .job__status,.upload-panel .upload-jobs .job.warning .progress{color:RGB(var(--warning))}.upload-panel .upload-jobs .job.critical .progress,.upload-panel .upload-jobs .job.success .progress,.upload-panel .upload-jobs .job.warning .progress{height:0}.upload-panel.open{background-color:rgba(var(--bg-dim),0.8)}.upload-panel.open .container{left:0}@media(max-width:800px){.upload-panel{width:100%;height:calc(100vh - 3.5rem);height:calc(100dvh - 3.5rem);left:0;bottom:3.5rem}.upload-panel .container{width:100%;height:95%;left:0;bottom:-100vh;border-radius:var(--rad) var(--rad) 0 0}.upload-panel .container #dragIndicator{display:block}.upload-panel.open .container{left:0;bottom:0}}.tag-icon{margin:0;padding:.25rem .5rem;display:flex;align-items:center;justify-content:center;gap:.25rem;font-size:.9rem;font-weight:500;text-decoration:none;border-radius:var(--rad-inner);border:none;background-color:RGBA(var(--primary),0.1);color:RGB(var(--primary));cursor:pointer;transition:background-color .2s ease-in-out,color .2s ease-in-out}.tag-icon svg{width:1.15rem;height:1.15rem}.tag-icon:hover{background-color:RGBA(var(--primary),0.3)}.navigation{margin:0;padding:0;width:3.5rem;height:100%;height:100dvh;display:flex;flex-direction:column;justify-content:space-between;position:fixed;top:0;left:0;background-color:RGB(var(--bg-100));color:RGB(var(--fg-white));z-index:69}.navigation .logo{margin:0;padding:0;width:3.5rem;height:3.5rem;min-height:3.5rem;display:flex;flex-direction:row;align-items:center}.navigation-spacer{height:100%}.navigation-item{margin:0;padding:0;width:3.5rem;height:3.5rem;min-height:3.5rem;position:relative;display:flex;flex-direction:row;justify-content:center;align-items:center;background-color:transparent;border:none;text-decoration:none}.navigation-item>svg{margin:0;padding:.5rem;width:2.5rem;height:2.5rem;border-radius:var(--rad-inner);color:RGB(var(--fg-white));transition:color .2s ease-out,transform .2s ease-out}.navigation-item .tool-tip{margin:0;padding:.4rem .7rem;display:block;position:absolute;top:50%;left:3rem;transform:translateY(-50%);font-size:.9rem;font-weight:500;background-color:RGB(var(--bg-100));color:RGB(var(--fg-white));opacity:0;border-radius:var(--rad-inner);transition:opacity .2s cubic-bezier(0.76,0,0.17,1),left .2s cubic-bezier(0.76,0,0.17,1);pointer-events:none}.navigation-item .tool-tip>svg{margin:0;font-size:1rem;width:.75rem;height:.75rem;display:block;position:absolute;top:50%;left:-0.45rem;transform:translateY(-50%);color:RGB(var(--bg-100))}.navigation-item:hover>svg{background:RGBA(var(--fg-white),0.1)}.navigation-item:hover span{opacity:1;left:3.9rem}.navigation-item.selected>svg{color:RGB(var(--primary))}.navigation-item.selected::before{content:'';display:block;position:absolute;top:3px;left:0;width:3px;height:calc(100% - 6px);background-color:RGB(var(--primary));border-radius:var(--rad-inner)}@media(max-width:800px){.navigation{width:100vw;height:3.5rem;flex-direction:row;justify-content:space-around;position:fixed;top:unset;bottom:0;left:0}.navigation>span{display:none}.navigation .logo{display:none}.navigation-item{margin:.25rem;padding:0;width:3rem;height:3rem;min-height:3rem}.navigation-item .tool-tip{display:none}.navigation-item.selected::before{top:unset;bottom:0;left:0;width:100%;height:3px}}.banner,.banner-small{width:100%;position:relative;color:RGB(var(--fg-white))}.banner .link,.banner-small .link{padding:.1rem .3rem;text-decoration:none;font-weight:500;background-color:RGB(var(--fg-white));color:RGB(var(--fg-black));border-radius:var(--rad-inner);cursor:pointer}.banner .link:hover,.banner-small .link:hover{background-color:RGB(var(--fg-black));color:RGB(var(--fg-white))}.banner::after,.banner-small::after{content:'';width:var(--rad);height:calc(var(--rad) * 2);position:absolute;bottom:calc(var(--rad) * -2);left:0;background-color:RGB(var(--bg-bright));border-radius:var(--rad) 0 0 0;box-shadow:0 calc(var(--rad) * -1) 0 0 RGB(var(--bg-100))}.banner{height:30rem;background-color:RGB(var(--bg-300))}.banner img{position:absolute;inset:0;width:100%;height:100%;background-color:inherit;object-fit:cover;object-position:center center}.banner .banner-filter{position:absolute;inset:0;width:100%;height:100%;background:linear-gradient(to right,RGB(var(--primary)),transparent);z-index:+1}.banner .banner-content{padding:.5rem;width:100%;height:auto;position:absolute;left:0;bottom:0;display:grid;grid-template-columns:1fr auto;grid-template-rows:1fr auto auto;grid-template-areas:'info info' 'header header' 'subtitle options';z-index:+2}.banner .banner-content .banner-header,.banner .banner-content .banner-info,.banner .banner-content .banner-subtitle{margin:0;padding:0;width:100%}.banner .banner-content .banner-header{grid-area:header;margin:.5rem 0;text-align:left;font-size:6.9rem;font-weight:700;color:RGB(var(--primary))}.banner .banner-content .banner-info{grid-area:info;font-size:1rem;font-weight:400}.banner .banner-content .banner-subtitle{grid-area:subtitle;font-size:1rem;font-weight:400}.banner .banner-content .pill-row{margin-top:auto;grid-area:options}.banner-small{height:3.5rem;background-color:RGB(var(--bg-100))}.banner-small .banner-content{padding:0 .5rem;width:100%;height:100%;position:absolute;inset:0;display:flex;flex-direction:row;justify-content:flex-start;z-index:+2}.banner-small .banner-content .banner-header,.banner-small .banner-content .banner-info{margin:auto 0;padding:0;width:auto;height:auto;justify-self:flex-start}.banner-small .banner-content .banner-header{margin-right:.6rem;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-align:left;font-weight:700;font-size:1.5rem;color:RGB(var(--primary))}.banner-small .banner-content .banner-info{margin-right:.6rem;font-size:.9rem;font-weight:400}.banner-small .banner-content .pill-row{margin-left:auto;width:auto}@media(max-width:800px){.banner::after,.banner-small::after{display:none}.banner{min-height:17rem;height:auto}.banner .banner-content{padding:.5rem;height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center}.banner .banner-content .banner-header{margin:1rem 0;text-align:center;font-size:2.5rem}.banner .banner-content .banner-info{font-size:1.1rem;text-align:center}.banner .banner-content .banner-subtitle{display:none}.banner .banner-content .pill-row{margin-top:0rem}.banner-small .banner-content .banner-info{display:none}}.gallery-grid{margin:0;padding:.35rem;width:100%;display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}.gallery-item{margin:.35rem;padding:0;height:auto;position:relative;border-radius:var(--rad-inner);box-shadow:0 .15rem .4rem .1rem RGBA(var(--bg-100),0.4);box-sizing:border-box;overflow:hidden;transition:box-shadow .2s cubic-bezier(0.79,0.14,0.15,0.86)}.gallery-item .image-filter{margin:0;padding:.5rem;width:100%;min-height:30%;height:auto;position:absolute;left:0;bottom:0;display:flex;flex-direction:column;justify-content:flex-end;background-image:linear-gradient(to top,rgba(var(--bg-100),0.69),transparent);opacity:0;z-index:+4;transition:opacity .2s cubic-bezier(0.79,0.14,0.15,0.86)}.gallery-item .image-filter .image-title,.gallery-item .image-filter .image-subtitle{margin:0;padding:0;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;color:RGB(var(--fg-white));text-shadow:0 0 2px RGB(var(--fg-black))}.gallery-item .image-filter .image-title{font-size:.9rem;font-weight:700}.gallery-item .image-filter .image-subtitle{font-size:.8rem;font-weight:400}.gallery-item img{width:100%;height:100%;position:absolute;inset:0;object-fit:cover;object-position:center;background-color:RGB(var(--bg-bright));filter:blur(0.5rem);opacity:0;transition:all .2s cubic-bezier(0.79,0.14,0.15,0.86)}.gallery-item img.loaded{filter:blur(0);opacity:1}.gallery-item:after{content:"";display:block;padding-bottom:100%}.gallery-item:hover{box-shadow:0 .2rem .4rem .1rem RGBA(var(--bg-100),0.6)}.gallery-item:hover .image-filter{opacity:1}.group-item{margin:.35rem;padding:0;height:auto;position:relative;border-radius:var(--rad-inner);box-sizing:border-box;overflow:hidden}.group-item .image-filter{margin:0;padding:.5rem;width:100%;min-height:30%;height:auto;position:absolute;left:0;bottom:0;display:flex;flex-direction:column;justify-content:flex-end;background-image:linear-gradient(to top,rgba(var(--bg-100),0.8),transparent);z-index:+4}.group-item .image-filter .image-title,.group-item .image-filter .image-subtitle{margin:0;padding:0;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;color:RGB(var(--fg-white));text-shadow:0 0 2px RGB(var(--fg-black))}.group-item .image-filter .image-title{font-size:.9rem;font-weight:700}.group-item .image-filter .image-subtitle{font-size:.8rem;font-weight:400}.group-item .images{margin:0;padding:0;width:100%;height:100%;position:absolute;inset:0;display:block}.group-item .images img{width:100%;height:100%;position:absolute;top:0;left:0;object-fit:cover;object-position:center;background-color:RGB(var(--bg-bright));border-radius:var(--rad-inner);box-shadow:0 0 .4rem .25rem RGBA(var(--bg-100),0.1);filter:blur(0.5rem);opacity:0;transition:all .2s cubic-bezier(0.79,0.14,0.15,0.86)}.group-item .images img.loaded{filter:blur(0);opacity:1}.group-item .images.size-1 .data-1{transform:scale(0.8) rotate(3deg)}.group-item .images.size-2 .data-1{transform:scale(0.7) rotate(-3deg) translate(10%,10%);z-index:+2}.group-item .images.size-2 .data-2{transform:scale(0.7) rotate(3deg) translate(-10%,-10%);z-index:+1}.group-item .images.size-3 .data-1{transform:scale(0.6) rotate(3deg) translate(-25%,25%);z-index:+3}.group-item .images.size-3 .data-2{transform:scale(0.6) rotate(-5deg) translate(25%,10%);z-index:+2}.group-item .images.size-3 .data-3{transform:scale(0.6) rotate(-1deg) translate(-15%,-23%);z-index:+1}.group-item:after{content:"";display:block;padding-bottom:100%}.group-item:hover .images.size-1 .data-1{transform:scale(0.9) rotate(0deg)}.group-item:hover .images.size-2 .data-1{transform:scale(0.75) rotate(-1deg) translate(12%,14%);z-index:+2}.group-item:hover .images.size-2 .data-2{transform:scale(0.75) rotate(1deg) translate(-12%,-10%);z-index:+1}.group-item:hover .images.size-3 .data-1{transform:scale(0.65) rotate(1deg) translate(-24%,24%);z-index:+3}.group-item:hover .images.size-3 .data-2{transform:scale(0.65) rotate(-2deg) translate(24%,10%);z-index:+2}.group-item:hover .images.size-3 .data-3{transform:scale(0.65) rotate(0deg) translate(-15%,-25%);z-index:+1}@media(max-width:800px){.gallery-grid{grid-template-columns:auto auto auto}}.top-of-page{margin:0;padding:0;width:auto;height:auto;position:fixed;bottom:.75rem;right:-3rem;display:flex;justify-content:center;align-items:center;background-color:RGB(var(--bg-300));color:RGB(var(--fg-white));border-radius:var(--rad);border:none;opacity:0;z-index:20;cursor:pointer;transition:all .2s cubic-bezier(0.86,0,0.07,1)}.top-of-page:hover{color:RGB(var(--primary))}.top-of-page svg{margin:.5rem;width:1.25rem;height:1.25rem}.top-of-page.show{right:.75rem;opacity:1}@media(max-width:800px){.top-of-page{bottom:4.25rem}}.info-button{margin:0;padding:0;width:auto;height:auto;position:fixed;bottom:.75rem;right:-3rem;display:flex;justify-content:center;align-items:center;background-color:RGB(var(--bg-300));color:RGB(var(--fg-white));border-radius:var(--rad);border:none;opacity:0;z-index:20;cursor:pointer;transition:all .2s cubic-bezier(0.86,0,0.07,1)}.info-button:hover{color:RGB(var(--info))}.info-button svg{margin:.5rem;width:1.25rem;height:1.25rem}.info-button.show{right:.75rem;opacity:1}@media(max-width:800px){.info-button{bottom:4.25rem}}.pill-row{margin:0;padding:0;width:100%;height:auto;display:flex;justify-content:center;align-items:center;gap:.5rem}.pill-row>div{margin:0;padding:0;display:flex;background-color:RGB(var(--bg-200));border-radius:var(--rad);box-shadow:0 1px 0 RGB(var(--bg-100)),0 -1px 0 RGB(var(--bg-300))}.pill-text{margin:0;padding:.5rem 1rem;width:auto;height:2.5rem;display:flex;justify-content:center;align-items:center;position:relative;text-align:center;font-size:1rem;font-weight:400;background-color:RGB(var(--bg-200));color:RGB(var(--fg-white));border-radius:var(--rad)}.pill-item{margin:0;padding:.5rem;width:2.5rem;height:2.5rem;display:flex;justify-content:center;align-items:center;position:relative;border:none;background-color:transparent;color:RGB(var(--fg-white))}.pill-item svg{width:1.25rem;height:1.25rem}.pill-item:hover{cursor:pointer;color:RGB(var(--primary))}.pill__critical{color:RGB(var(--critical))}.pill__critical span{background:RGB(var(--critical));color:RGB(var(--fg-white))}.pill__critical span svg{color:RGB(var(--critical))}.pill__critical:hover{color:RGB(var(--fg-white))}.pill__info{color:RGB(var(--info))}.pill__info span{color:RGB(var(--info))}.pill__info:hover{color:RGB(var(--fg-white))}@media(max-width:800px){.tool-tip{display:none}}.btn-block{padding:.4rem .7rem;width:auto;min-height:2.3rem;display:flex;justify-content:center;align-items:center;gap:.5rem;position:relative;font-size:1rem;font-weight:400;text-align:center;background-color:RGBA(var(--white),0.1);color:RGB(var(--white));border:none;border-radius:var(--rad-inner);box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--white),0.2);outline:none;cursor:pointer;transition:background-color .15s ease-in-out,color .15s ease-in-out,box-shadow .15s ease-in-out}.btn-block:hover,.btn-block:focus-visible{background-color:RGBA(var(--white),0.2);box-shadow:0 1px 0 RGBA(var(--black),0.3),0 -1px 0 RGBA(var(--white),0.3)}.btn-block.primary{color:RGB(var(--primary));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--white),0.2)}.btn-block.primary:hover,.btn-block.primary:focus-visible{background-color:RGBA(var(--primary),0.1);color:RGB(var(--primary));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--primary),0.2)}.btn-block.critical{color:RGB(var(--critical));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--white),0.2)}.btn-block.critical:hover,.btn-block.critical:focus-visible{background-color:RGBA(var(--critical),0.1);color:RGB(var(--critical));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--critical),0.2)}.btn-block.warning{color:RGB(var(--warning));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--white),0.2)}.btn-block.warning:hover,.btn-block.warning:focus-visible{background-color:RGBA(var(--warning),0.1);color:RGB(var(--warning));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--warning),0.2)}.btn-block.success{color:RGB(var(--success));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--white),0.2)}.btn-block.success:hover,.btn-block.success:focus-visible{background-color:RGBA(var(--success),0.1);color:RGB(var(--success));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--success),0.2)}.btn-block.info{color:RGB(var(--info));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--white),0.2)}.btn-block.info:hover,.btn-block.info:focus-visible{background-color:RGBA(var(--info),0.1);color:RGB(var(--info));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--info),0.2)}.btn-block.black{color:RGB(var(--black));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--white),0.2)}.btn-block.black:hover,.btn-block.black:focus-visible{background-color:RGBA(var(--black),0.1);color:RGB(var(--black));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--black),0.2)}.input-checkbox{padding:0;display:flex;justify-content:flex-start;align-items:center;gap:.5rem;position:relative}.input-checkbox label{font-size:1rem;font-weight:400;text-align:left;color:RGB(var(--fg-white))}.input-block{padding:.4rem .7rem;width:auto;min-height:2.3rem;display:flex;justify-content:flex-start;align-items:center;position:relative;font-size:1rem;font-weight:400;text-align:left;background-color:RGBA(var(--white),0.1);color:RGB(var(--white));border:none;border-bottom:3px solid RGBA(var(--white),0.1);border-radius:var(--rad-inner);box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--white),0.2);outline:none;cursor:pointer;transition:background-color .2s ease-in-out,color .2s ease-in-out}.input-block:not(:focus):not([value=""]):not(:placeholder-shown){border-color:RGBA(var(--white),0.3)}.input-block:hover{border-color:RGBA(var(--white),0.3)}.input-block:focus{border-color:RGB(var(--primary))}.input-block.black{color:RGB(var(--black));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--white),0.2)}.input-block.black:hover,.input-block.black:focus-visible{background-color:RGBA(var(--black),0.1);color:RGB(var(--black));box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--black),0.2)}.fileDrop-block{padding:1rem 1.25rem;width:100%;min-height:2.3rem;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:.5rem;position:relative;font-size:1rem;font-weight:400;text-align:center;background-color:RGBA(var(--white),0.1);color:RGB(var(--white));border:none;border-radius:var(--rad-inner);box-shadow:0 1px 0 RGBA(var(--black),0.2),0 -1px 0 RGBA(var(--white),0.2);outline:none;cursor:pointer;overflow:hidden;transition:background-color .2s ease-in-out,color .2s ease-in-out,box-shadow .15s ease-in-out}.fileDrop-block input{position:absolute;inset:0;opacity:0;cursor:pointer}.fileDrop-block .status{width:100%;white-space:nowrap;text-overflow:ellipsis;text-align:center;overflow:hidden}.fileDrop-block:hover,.fileDrop-block:focus-visible{background-color:RGBA(var(--white),0.2);color:RGB(var(--white));box-shadow:0 1px 0 RGBA(var(--black),0.3),0 -1px 0 RGBA(var(--white),0.3)}.fileDrop-block.active{background-color:RGBA(var(--primary),0.2);color:RGB(var(--primary));box-shadow:0 1px 0 RGBA(var(--black),0.3),0 -1px 0 RGBA(var(--primary),0.3)}.fileDrop-block.edging{background-color:RGBA(var(--white),0.2);color:RGB(var(--white));box-shadow:0 1px 0 RGBA(var(--black),0.3),0 -1px 0 RGBA(var(--white),0.3)}.fileDrop-block.edging input{display:none}.fileDrop-block.error{background-color:RGBA(var(--critical),0.2);color:RGB(var(--critical));box-shadow:0 1px 0 RGBA(var(--black),0.3),0 -1px 0 RGBA(var(--critical),0.3)}.background{width:100%;height:100vh;position:fixed;top:0;left:0;background-color:RGB(var(--bg-300));background-image:linear-gradient(to right,RGB(var(--bg-400)) 15%,RGB(var(--bg-200)) 35%,RGB(var(--bg-400)) 50%);background-size:1000px 640px;animation:imgLoading 1.8s linear infinite forwards;user-select:none;overflow:hidden;z-index:1}.background img{position:absolute;top:0;left:0;width:100%;height:100%;background-color:RGB(var(--fg-white));filter:blur(1rem) saturate(1.2);transform:scale(1.1);object-fit:cover;object-position:center center}.background span{position:absolute;top:0;left:0;width:100%;height:100%;z-index:+1}.info-container{width:27rem;height:100vh;position:absolute;top:0;left:0;display:flex;flex-direction:column;gap:0;background-color:RGB(var(--bg-200));overflow-y:auto;z-index:+4;transition:left .3s cubic-bezier(0.76,0,0.17,1)}.info-container.collapsed{left:-27rem}.info-tab{width:100%;display:flex;flex-direction:column;position:relative;background-color:RGB(var(--bg-200));border-radius:var(--rad);transition:max-height .3s cubic-bezier(0.79,0.14,0.15,0.86)}.info-tab.collapsed{height:2.5rem}.info-tab.collapsed .collapse-indicator{transform:rotate(90deg)}.info-tab.collapsed .info-table{height:0;padding:0}.collapse-indicator{margin:0;padding:0;width:1.25rem;height:1.25rem;position:absolute;top:.6rem;right:.6rem;background-color:transparent;color:RGB(var(--primary));border:none;z-index:+2;transition:transform .15s cubic-bezier(0.79,0.14,0.15,0.86);cursor:pointer}.info-header{margin:0;padding:.5rem;width:100%;height:2.5rem;display:flex;justify-content:start;align-items:center;gap:.5rem;position:sticky;top:0;z-index:+1;background-color:RGB(var(--bg-200))}.info-header svg{margin:0;padding:0;width:1.25rem;height:1.25rem;fill:RGB(var(--primary))}.info-header h2{margin:0;padding:0;font-size:1.1rem;font-weight:500;color:RGB(var(--primary));text-overflow:ellipsis;overflow:hidden}.info-table{margin:0;padding:.5rem;display:flex;flex-direction:column;gap:1rem;color:RGB(var(--fg-white));overflow-x:hidden}.info-table p{margin:0;padding:0;font-size:1rem;font-weight:400;text-overflow:ellipsis;overflow:hidden}.info-table .link{margin:0;padding:0;color:RGB(var(--primary));cursor:pointer;text-decoration:none}.info-table .link:hover{text-decoration:underline}.info-table table{margin:0;padding:0;width:100%;overflow-x:hidden;border-collapse:collapse}.info-table table tr{white-space:nowrap}.info-table table tr td{padding-bottom:.5rem;max-width:0;font-size:1rem;font-weight:400;vertical-align:top}.info-table table tr td:first-child{padding-right:.5rem;width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.info-table table tr td:last-child{width:50%;white-space:normal;word-break:break-word}.info-table table tr:last-of-type td{padding-bottom:0}.img-colours{width:100%;display:flex;gap:.5rem}.img-colours span{margin:0;padding:0;width:1.5rem;height:1.5rem;display:flex;justify-content:center;align-items:center;border-radius:var(--rad-inner)}.img-groups{width:100%;display:flex;flex-wrap:wrap;gap:.5rem}@media(max-width:1100px){.info-container{width:100%;height:100%;position:relative;display:flex;flex-direction:column;gap:.5rem}.info-container.collapsed{left:unset}}.image-container{margin:auto;padding:.5rem;width:100%;height:100%;display:flex;overflow:hidden}.image-container img{margin:auto;padding:0;width:auto;height:auto;max-width:100%;max-height:100%;object-fit:contain;object-position:center}.image-grid{padding:0;width:100%;height:100vh;position:relative;display:flex;flex-direction:column;gap:.5rem;z-index:3}.image-grid .image-block{margin:0 0 0 27rem;padding:0;width:calc(100% - 27rem);height:100vh;position:relative;display:flex;flex-direction:column;gap:0;z-index:3;transition:margin .3s cubic-bezier(0.76,0,0.17,1),width .3s cubic-bezier(0.76,0,0.17,1)}.image-grid .image-block .pill-row{margin-bottom:.5rem}.image-grid.collapsed .image-block{margin:0;width:100%}@media(max-width:1100px){.image-grid{padding:.5rem;height:auto}.image-grid .image-block{margin:0;width:100%;height:auto;gap:.5rem;transition:margin 0s,width 0s}.image-grid .image-block .image-container{margin:0 auto;padding:0;max-height:69vh}.image-grid .image-block .image-container img{max-height:69vh}.image-grid .image-block .pill-row{margin-bottom:0}.image-grid .image-block .pill-row #fullscreenImage{display:none}.info-container{background:transparent}.info-header{border-radius:var(--rad) var(--rad) 0 0}.info-tab.collapsed .info-header{border-radius:var(--rad)}}*{box-sizing:border-box;font-family:"Rubik",sans-serif;scrollbar-color:RGB(var(--primary)) transparent}* ::-webkit-scrollbar{width:.5rem}* ::-webkit-scrollbar-track{background:RGB(var(--bg-200))}* ::-webkit-scrollbar-thumb{background:RGB(var(--primary))}* ::-webkit-scrollbar-thumb:hover{background:RGB(var(--fg-white))}html,body{margin:0;padding:0;min-height:100vh;max-width:100vw;background-color:RGB(var(--fg-white));scroll-behavior:smooth;overflow-x:hidden}.wrapper{margin:0;padding:0 0 0 3.5rem;min-height:100vh;display:flex;flex-direction:column;background-color:RGB(var(--bg-bright));color:RGB(var(--bg-100))}.big-text{height:20rem;display:flex;flex-direction:column;justify-content:center;align-items:center;color:RGB(var(--bg-100))}.big-text h1{margin:0 2rem;font-size:4rem;font-weight:900;text-align:center}.big-text p{margin:0 2rem;max-width:40rem;font-size:1rem;font-weight:400;text-align:center}.error-page{width:100%;height:100vh;display:flex;flex-direction:column;justify-content:center;align-items:center;background-color:RGB(var(--bg-bright))}.error-page h1{margin:0 2rem;font-size:6.9rem;font-weight:900;text-align:center;color:var(--primary)}.error-page p{margin:0 2rem;max-width:40rem;font-size:1.25rem;font-weight:400;text-align:center;color:var(--fg-black)}@media(max-width:800px){.wrapper{padding:0 0 3.5rem 0}.big-text{height:calc(75vh - 3.5rem)}.big-text h1{font-size:3.5rem}.error-page{height:calc(100vh - 3.5rem)}.error-page h1{font-size:4.5rem}.error-page p{max-width:100%;font-size:1rem}}:root{--bg-dim:16,16,16;--bg-bright:232,227,227;--bg-100:21,21,21;--bg-200:26.1,26.1,26.1;--bg-300:31.2,31.2,31.2;--bg-400:36.3,36.3,36.3;--bg-500:41.4,41.4,41.4;--bg-600:46.5,46.5,46.5;--fg-dim:102,102,102;--fg-white:232,227,227;--fg-black:16,16,16;--black:21,21,21;--white:232,227,227;--red:182,100,103;--orange:217,140,95;--yellow:217,188,140;--green:140,151,125;--blue:141,163,185;--purple:169,136,176;--primary:var(--green);--warning:var(--orange);--critical:var(--red);--success:var(--green);--info:var(--blue);--rad:6px;--rad-inner:calc(var(--rad) / 2);--animation-smooth:cubic-bezier(0.76,0,0.17,1);--animation-bounce:cubic-bezier(.68,-0.55,.27,1.55);--breakpoint:800px} \ No newline at end of file diff --git a/gallery/static/icon.png b/onlylegs/static/icon.png similarity index 100% rename from gallery/static/icon.png rename to onlylegs/static/icon.png diff --git a/gallery/static/js/index.js b/onlylegs/static/js/index.js similarity index 100% rename from gallery/static/js/index.js rename to onlylegs/static/js/index.js diff --git a/gallery/static/js/login.js b/onlylegs/static/js/login.js similarity index 100% rename from gallery/static/js/login.js rename to onlylegs/static/js/login.js diff --git a/gallery/static/js/notifications.js b/onlylegs/static/js/notifications.js similarity index 100% rename from gallery/static/js/notifications.js rename to onlylegs/static/js/notifications.js diff --git a/gallery/static/js/popup.js b/onlylegs/static/js/popup.js similarity index 100% rename from gallery/static/js/popup.js rename to onlylegs/static/js/popup.js diff --git a/gallery/static/js/uploadTab.js b/onlylegs/static/js/uploadTab.js similarity index 100% rename from gallery/static/js/uploadTab.js rename to onlylegs/static/js/uploadTab.js diff --git a/gallery/static/js/webp.js b/onlylegs/static/js/webp.js similarity index 100% rename from gallery/static/js/webp.js rename to onlylegs/static/js/webp.js diff --git a/gallery/static/logo-black.svg b/onlylegs/static/logo-black.svg similarity index 100% rename from gallery/static/logo-black.svg rename to onlylegs/static/logo-black.svg diff --git a/gallery/static/logo-white.svg b/onlylegs/static/logo-white.svg similarity index 100% rename from gallery/static/logo-white.svg rename to onlylegs/static/logo-white.svg diff --git a/gallery/static/manifest.json b/onlylegs/static/manifest.json similarity index 100% rename from gallery/static/manifest.json rename to onlylegs/static/manifest.json diff --git a/gallery/static/sass/animations.sass b/onlylegs/static/sass/animations.sass similarity index 100% rename from gallery/static/sass/animations.sass rename to onlylegs/static/sass/animations.sass diff --git a/gallery/static/sass/components/banner.sass b/onlylegs/static/sass/components/banner.sass similarity index 100% rename from gallery/static/sass/components/banner.sass rename to onlylegs/static/sass/components/banner.sass diff --git a/gallery/static/sass/components/buttons/block.sass b/onlylegs/static/sass/components/buttons/block.sass similarity index 100% rename from gallery/static/sass/components/buttons/block.sass rename to onlylegs/static/sass/components/buttons/block.sass diff --git a/gallery/static/sass/components/buttons/info-button.sass b/onlylegs/static/sass/components/buttons/info-button.sass similarity index 100% rename from gallery/static/sass/components/buttons/info-button.sass rename to onlylegs/static/sass/components/buttons/info-button.sass diff --git a/gallery/static/sass/components/buttons/pill.sass b/onlylegs/static/sass/components/buttons/pill.sass similarity index 100% rename from gallery/static/sass/components/buttons/pill.sass rename to onlylegs/static/sass/components/buttons/pill.sass diff --git a/gallery/static/sass/components/buttons/top-of-page.sass b/onlylegs/static/sass/components/buttons/top-of-page.sass similarity index 100% rename from gallery/static/sass/components/buttons/top-of-page.sass rename to onlylegs/static/sass/components/buttons/top-of-page.sass diff --git a/gallery/static/sass/components/gallery.sass b/onlylegs/static/sass/components/gallery.sass similarity index 100% rename from gallery/static/sass/components/gallery.sass rename to onlylegs/static/sass/components/gallery.sass diff --git a/gallery/static/sass/components/image-view/background.sass b/onlylegs/static/sass/components/image-view/background.sass similarity index 100% rename from gallery/static/sass/components/image-view/background.sass rename to onlylegs/static/sass/components/image-view/background.sass diff --git a/gallery/static/sass/components/image-view/image.sass b/onlylegs/static/sass/components/image-view/image.sass similarity index 100% rename from gallery/static/sass/components/image-view/image.sass rename to onlylegs/static/sass/components/image-view/image.sass diff --git a/gallery/static/sass/components/image-view/info-tab.sass b/onlylegs/static/sass/components/image-view/info-tab.sass similarity index 100% rename from gallery/static/sass/components/image-view/info-tab.sass rename to onlylegs/static/sass/components/image-view/info-tab.sass diff --git a/gallery/static/sass/components/image-view/view.sass b/onlylegs/static/sass/components/image-view/view.sass similarity index 100% rename from gallery/static/sass/components/image-view/view.sass rename to onlylegs/static/sass/components/image-view/view.sass diff --git a/gallery/static/sass/components/navigation.sass b/onlylegs/static/sass/components/navigation.sass similarity index 100% rename from gallery/static/sass/components/navigation.sass rename to onlylegs/static/sass/components/navigation.sass diff --git a/gallery/static/sass/components/notification.sass b/onlylegs/static/sass/components/notification.sass similarity index 100% rename from gallery/static/sass/components/notification.sass rename to onlylegs/static/sass/components/notification.sass diff --git a/gallery/static/sass/components/pop-up.sass b/onlylegs/static/sass/components/pop-up.sass similarity index 100% rename from gallery/static/sass/components/pop-up.sass rename to onlylegs/static/sass/components/pop-up.sass diff --git a/gallery/static/sass/components/tags.sass b/onlylegs/static/sass/components/tags.sass similarity index 100% rename from gallery/static/sass/components/tags.sass rename to onlylegs/static/sass/components/tags.sass diff --git a/gallery/static/sass/components/upload-panel.sass b/onlylegs/static/sass/components/upload-panel.sass similarity index 100% rename from gallery/static/sass/components/upload-panel.sass rename to onlylegs/static/sass/components/upload-panel.sass diff --git a/gallery/static/sass/style.sass b/onlylegs/static/sass/style.sass similarity index 100% rename from gallery/static/sass/style.sass rename to onlylegs/static/sass/style.sass diff --git a/gallery/static/sass/variables.sass b/onlylegs/static/sass/variables.sass similarity index 100% rename from gallery/static/sass/variables.sass rename to onlylegs/static/sass/variables.sass diff --git a/gallery/templates/error.html b/onlylegs/templates/error.html similarity index 100% rename from gallery/templates/error.html rename to onlylegs/templates/error.html diff --git a/gallery/templates/group.html b/onlylegs/templates/group.html similarity index 100% rename from gallery/templates/group.html rename to onlylegs/templates/group.html diff --git a/gallery/templates/image.html b/onlylegs/templates/image.html similarity index 100% rename from gallery/templates/image.html rename to onlylegs/templates/image.html diff --git a/gallery/templates/index.html b/onlylegs/templates/index.html similarity index 100% rename from gallery/templates/index.html rename to onlylegs/templates/index.html diff --git a/gallery/templates/layout.html b/onlylegs/templates/layout.html similarity index 100% rename from gallery/templates/layout.html rename to onlylegs/templates/layout.html diff --git a/gallery/templates/list.html b/onlylegs/templates/list.html similarity index 100% rename from gallery/templates/list.html rename to onlylegs/templates/list.html diff --git a/gallery/templates/profile.html b/onlylegs/templates/profile.html similarity index 100% rename from gallery/templates/profile.html rename to onlylegs/templates/profile.html diff --git a/gallery/templates/settings/account.html b/onlylegs/templates/settings/account.html similarity index 100% rename from gallery/templates/settings/account.html rename to onlylegs/templates/settings/account.html diff --git a/gallery/templates/settings/general.html b/onlylegs/templates/settings/general.html similarity index 100% rename from gallery/templates/settings/general.html rename to onlylegs/templates/settings/general.html diff --git a/gallery/templates/settings/logs.html b/onlylegs/templates/settings/logs.html similarity index 100% rename from gallery/templates/settings/logs.html rename to onlylegs/templates/settings/logs.html diff --git a/gallery/templates/settings/server.html b/onlylegs/templates/settings/server.html similarity index 100% rename from gallery/templates/settings/server.html rename to onlylegs/templates/settings/server.html diff --git a/gallery/templates/settings/settings_layout.html b/onlylegs/templates/settings/settings_layout.html similarity index 100% rename from gallery/templates/settings/settings_layout.html rename to onlylegs/templates/settings/settings_layout.html diff --git a/gallery/utils/__init__.py b/onlylegs/utils/__init__.py similarity index 100% rename from gallery/utils/__init__.py rename to onlylegs/utils/__init__.py diff --git a/gallery/utils/contrast.py b/onlylegs/utils/contrast.py similarity index 100% rename from gallery/utils/contrast.py rename to onlylegs/utils/contrast.py diff --git a/gallery/utils/generate_image.py b/onlylegs/utils/generate_image.py similarity index 100% rename from gallery/utils/generate_image.py rename to onlylegs/utils/generate_image.py diff --git a/gallery/utils/metadata/__init__.py b/onlylegs/utils/metadata/__init__.py similarity index 100% rename from gallery/utils/metadata/__init__.py rename to onlylegs/utils/metadata/__init__.py diff --git a/gallery/utils/metadata/helpers.py b/onlylegs/utils/metadata/helpers.py similarity index 100% rename from gallery/utils/metadata/helpers.py rename to onlylegs/utils/metadata/helpers.py diff --git a/gallery/utils/metadata/mapping.py b/onlylegs/utils/metadata/mapping.py similarity index 100% rename from gallery/utils/metadata/mapping.py rename to onlylegs/utils/metadata/mapping.py diff --git a/gallery/views/__init__.py b/onlylegs/views/__init__.py similarity index 100% rename from gallery/views/__init__.py rename to onlylegs/views/__init__.py diff --git a/gallery/views/group.py b/onlylegs/views/group.py similarity index 96% rename from gallery/views/group.py rename to onlylegs/views/group.py index 53557cd..7fe1bdc 100644 --- a/gallery/views/group.py +++ b/onlylegs/views/group.py @@ -5,9 +5,9 @@ sounds more limiting that it actually is in this gallery """ from flask import Blueprint, render_template, url_for -from gallery.models import Post, User, GroupJunction, Group -from gallery.extensions import db -from gallery.utils import contrast +from onlylegs.models import Post, User, GroupJunction, Group +from onlylegs.extensions import db +from onlylegs.utils import contrast blueprint = Blueprint("group", __name__, url_prefix="/group") diff --git a/gallery/views/image.py b/onlylegs/views/image.py similarity index 96% rename from gallery/views/image.py rename to onlylegs/views/image.py index b1de219..a192f15 100644 --- a/gallery/views/image.py +++ b/onlylegs/views/image.py @@ -3,8 +3,8 @@ Onlylegs - Image View """ from math import ceil from flask import Blueprint, render_template, url_for, current_app -from gallery.models import Post, GroupJunction, Group -from gallery.extensions import db +from onlylegs.models import Post, GroupJunction, Group +from onlylegs.extensions import db blueprint = Blueprint("image", __name__, url_prefix="/image") diff --git a/gallery/views/index.py b/onlylegs/views/index.py similarity index 97% rename from gallery/views/index.py rename to onlylegs/views/index.py index b676f1e..3cc0155 100644 --- a/gallery/views/index.py +++ b/onlylegs/views/index.py @@ -6,7 +6,7 @@ from math import ceil from flask import Blueprint, render_template, request, current_app from werkzeug.exceptions import abort -from gallery.models import Post +from onlylegs.models import Post blueprint = Blueprint("gallery", __name__) diff --git a/gallery/views/profile.py b/onlylegs/views/profile.py similarity index 96% rename from gallery/views/profile.py rename to onlylegs/views/profile.py index cfe7007..bde1330 100644 --- a/gallery/views/profile.py +++ b/onlylegs/views/profile.py @@ -5,7 +5,7 @@ from flask import Blueprint, render_template, request from werkzeug.exceptions import abort from flask_login import current_user -from gallery.models import Post, User +from onlylegs.models import Post, User blueprint = Blueprint("profile", __name__, url_prefix="/profile") diff --git a/gallery/views/settings.py b/onlylegs/views/settings.py similarity index 100% rename from gallery/views/settings.py rename to onlylegs/views/settings.py diff --git a/run.py b/run.py index b7efc15..28a7d1f 100644 --- a/run.py +++ b/run.py @@ -25,7 +25,7 @@ Configuration() if DEBUG: - from gallery import create_app + from onlylegs import create_app create_app().run(host=ADDRESS, port=PORT, debug=True, threaded=True) else: