:root{--bg:#fff;--panel:#fafafa;--text:#161616;--muted:#707070;--line:#e6e6e6;--accent:#ff6b35;--hover:#f2f2f2;--shadow:0 8px 30px rgba(0,0,0,.14);--sidebar:230px}*{box-sizing:border-box}html,body,#app{margin:0;min-height:100%;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;background:var(--bg);color:var(--text)}button,input{font:inherit}button{color:inherit}.hidden{display:none!important}.sidebar{position:fixed;left:0;top:0;bottom:0;width:var(--sidebar);padding:18px 12px;border-right:1px solid var(--line);background:var(--panel);z-index:20}.brand{height:52px;display:flex;gap:11px;align-items:center;padding:0 12px;font-size:20px;font-weight:700}.brand-mark{color:var(--accent);font-size:27px}.sidebar nav{display:grid;gap:4px;margin-top:15px}.nav{display:flex;align-items:center;gap:14px;border:0;background:transparent;padding:11px 13px;border-radius:9px;text-align:left;cursor:pointer}.nav:hover,.nav.active{background:var(--hover)}.nav.active{font-weight:650}.nav small{margin-left:auto;color:var(--muted);font-size:10px}.future{opacity:.45;cursor:default}.sidebar-foot{position:absolute;bottom:18px;left:24px;right:24px;display:grid;gap:2px;font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis}.sidebar-foot strong{color:var(--text);font-weight:650;overflow:hidden;text-overflow:ellipsis}.sidebar-label{text-transform:uppercase;letter-spacing:.06em;font-size:9px}main{margin-left:var(--sidebar);min-height:100vh}.topbar{height:70px;position:sticky;top:0;display:flex;align-items:center;gap:18px;padding:0 26px;border-bottom:1px solid var(--line);background:color-mix(in srgb,var(--bg) 92%,transparent);backdrop-filter:blur(10px);z-index:15}.search-wrap{margin:auto;display:flex;align-items:center;gap:8px;width:min(620px,60vw);background:var(--hover);border-radius:24px;padding:9px 15px}.search-wrap input{width:100%;border:0;outline:0;background:transparent;color:var(--text)}.icon-button,.user-button,.back{border:0;background:transparent;cursor:pointer;border-radius:8px;padding:8px}.icon-button:hover,.user-button:hover,.back:hover{background:var(--hover)}.user-button{white-space:nowrap}#menu-button{display:none}.content{padding:26px 30px 80px;max-width:1800px;margin:auto}.page-head{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;margin-bottom:24px}.page-head h1{margin:4px 0;font-size:30px}.page-head p{margin:0;color:var(--muted)}.count{color:var(--muted);font-size:14px;white-space:nowrap}.album-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:24px}.album-card{cursor:pointer;outline:none}.album-card:focus-visible .album-cover{outline:3px solid color-mix(in srgb,var(--accent) 65%,transparent);outline-offset:3px}.album-cover{position:relative;aspect-ratio:1.35;background:#ececec;border-radius:12px;overflow:hidden;box-shadow:0 1px 2px rgba(0,0,0,.06)}.album-cover img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .2s}.album-card:hover img{transform:scale(1.025)}.album-card h3{margin:10px 2px 3px;font-size:16px}.album-card p{margin:0 2px;color:var(--muted);font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.timeline{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:4px}.asset{position:relative;aspect-ratio:1;background:#ececec;overflow:hidden;cursor:pointer;border:0;padding:0}.asset img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .12s}.asset:hover img,.asset:focus-visible img{transform:scale(1.025)}.asset:focus-visible{outline:3px solid var(--accent);outline-offset:-3px}.asset .video-badge{position:absolute;right:8px;bottom:8px;background:rgba(0,0,0,.65);color:white;border-radius:15px;padding:4px 7px;font-size:12px}.asset .album-badge{position:absolute;left:7px;bottom:7px;max-width:calc(100% - 14px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:rgba(0,0,0,.68);color:#fff;border-radius:5px;padding:4px 7px;font-size:11px}.asset.deleted{opacity:.45}.empty{padding:100px 20px;text-align:center;color:var(--muted)}.setup{padding:8vh 24px}.setup-card{max-width:440px;margin:auto;border:1px solid var(--line);border-radius:14px;padding:28px;box-shadow:var(--shadow)}.setup-card p,.dialog-note{color:var(--muted)}label{display:grid;gap:6px;margin:14px 0;font-size:13px;color:var(--muted)}label input{padding:10px 12px;border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--text)}.primary{border:0;border-radius:8px;padding:10px 16px;background:var(--accent);color:white;font-weight:650;cursor:pointer}.modal{position:fixed;inset:0;background:rgba(0,0,0,.45);display:grid;place-items:center;z-index:50}.dialog{width:min(390px,calc(100vw - 30px));background:var(--bg);padding:28px;border-radius:14px;box-shadow:var(--shadow);position:relative}.dialog h2{margin-top:0;margin-bottom:6px}.dialog-note{margin-top:0;font-size:13px}.dialog-close{position:absolute;right:12px;top:10px;border:0;background:transparent;font-size:24px;cursor:pointer}.error{min-height:20px;color:#c33;font-size:13px;margin-bottom:8px}.viewer{position:fixed;inset:0;background:#111;color:#fff;z-index:60;display:grid;grid-template-columns:1fr;grid-template-rows:54px 1fr}.viewer-bar{grid-column:1;display:flex;align-items:center;gap:12px;padding:5px 10px;background:#171717;z-index:7}.viewer-bar #viewer-position{margin-right:auto;color:#bbb;font-size:13px}.viewer .icon-button{color:#fff;text-decoration:none}.viewer .icon-button:hover{background:#333}.media{grid-column:1;display:grid;place-items:center;min-width:0;min-height:0;padding:16px;position:relative}.media img,.media video{max-width:100%;max-height:calc(100vh - 86px);object-fit:contain}.info-panel{position:absolute;right:0;top:54px;bottom:0;width:min(350px,90vw);z-index:6;background:#f8f8f8;color:#222;padding:18px 22px;overflow:auto;box-shadow:-10px 0 30px rgba(0,0,0,.16)}.info-panel h2{margin-top:5px}.info-panel dl{margin:0}.info-panel dt{margin-top:15px;color:#777;font-size:11px;text-transform:uppercase;letter-spacing:.06em}.info-panel dd{margin:4px 0;white-space:pre-wrap;overflow-wrap:anywhere}.viewer-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:4;border:0;background:rgba(0,0,0,.35);color:#fff;width:45px;height:65px;font-size:42px;cursor:pointer}.viewer-nav:hover{background:rgba(0,0,0,.65)}.viewer-nav:disabled{opacity:.18;cursor:default}.viewer-nav.prev{left:10px}.viewer-nav.next{right:10px}.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:#222;color:#fff;padding:10px 16px;border-radius:8px;z-index:100;box-shadow:var(--shadow)}@media(max-width:850px){:root{--sidebar:0px}.sidebar{transform:translateX(-240px);width:230px;transition:transform .2s}.sidebar.open{transform:translateX(0);box-shadow:var(--shadow)}main{margin-left:0}#menu-button{display:block}.topbar{padding:0 10px;gap:8px}.search-wrap{width:auto;flex:1}.user-button{font-size:13px;padding:8px 6px}.content{padding:20px 10px 70px}.page-head{align-items:flex-start}.page-head h1{font-size:25px}.timeline{grid-template-columns:repeat(3,1fr);gap:2px}.album-grid{grid-template-columns:repeat(2,1fr);gap:14px}.album-card h3{font-size:14px}.album-card p{font-size:11px}}@media(max-width:520px){.timeline{grid-template-columns:repeat(3,1fr)}.album-grid{grid-template-columns:1fr 1fr}.search-wrap{padding:8px 11px}.search-wrap input{min-width:0}.count{font-size:12px}}@media(prefers-color-scheme:dark){:root{--bg:#181818;--panel:#202020;--text:#eee;--muted:#aaa;--line:#333;--hover:#2c2c2c}.album-cover,.asset{background:#292929}.info-panel{background:#202020;color:#eee}.info-panel dt{color:#aaa}}
.duplicates{display:grid;gap:28px}.duplicate-group{border:1px solid var(--line);border-radius:14px;padding:16px;background:var(--panel)}.duplicate-head{display:flex;justify-content:space-between;gap:20px;align-items:flex-start;margin-bottom:14px}.duplicate-head h2{margin:0 0 5px;font-size:18px}.duplicate-head p{margin:0;color:var(--muted);font-size:13px;max-width:780px}.duplicate-head strong{white-space:nowrap;color:var(--muted);font-size:13px}.duplicate-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}.duplicate-tile{border:0;padding:0;background:var(--bg);border-radius:10px;overflow:hidden;cursor:pointer;text-align:left}.duplicate-tile img{display:block;width:100%;aspect-ratio:1.25;object-fit:cover;background:var(--hover)}.duplicate-tile:hover img,.duplicate-tile:focus-visible img{filter:brightness(.94)}.duplicate-tile:focus-visible{outline:3px solid var(--accent);outline-offset:2px}.duplicate-meta{display:block;padding:8px 9px;color:var(--muted);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.duplicate-exact{border-left:4px solid var(--accent)}.duplicate-normalized{border-left:4px solid #7d8cff}.duplicate-visual{border-left:4px solid #999}@media(max-width:850px){.duplicate-grid{grid-template-columns:repeat(2,1fr)}.duplicate-head{display:block}.duplicate-head strong{display:block;margin-top:8px}}

.timeline.photos-timeline{display:block}.timeline-day{margin:0 0 30px}.timeline-day-title{margin:0 0 10px;font-size:18px;font-weight:650}.timeline-day-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:4px}.load-more-wrap{text-align:center;margin:28px 0 6px}.load-more-wrap .primary:disabled{opacity:.55;cursor:wait}@media(max-width:850px){.timeline-day{margin-bottom:22px}.timeline-day-title{font-size:16px;margin:0 4px 8px}.timeline-day-grid{grid-template-columns:repeat(3,1fr);gap:2px}}

/* 2.1.1b duplicate resolution */
.duplicate-head-actions{display:flex;align-items:flex-end;gap:10px;flex-direction:column}.duplicate-action{border:1px solid var(--line);border-radius:7px;background:var(--bg);padding:7px 10px;cursor:pointer;font-size:12px}.duplicate-action:hover:not(:disabled){background:var(--hover)}.duplicate-action.keep{font-weight:650}.duplicate-action.danger{border-color:#c55;color:#b33}.duplicate-action:disabled{opacity:.45;cursor:default}.duplicate-tile{border:1px solid var(--line);background:var(--bg)}.duplicate-image-button{display:block;width:100%;border:0;padding:0;background:transparent;cursor:pointer}.duplicate-image-button img{display:block;width:100%;aspect-ratio:1.25;object-fit:cover;background:var(--hover)}.duplicate-image-button:hover img,.duplicate-image-button:focus-visible img{filter:brightness(.94)}.duplicate-image-button:focus-visible{outline:3px solid var(--accent);outline-offset:-3px}.duplicate-tile-actions{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 9px 9px;flex-wrap:wrap}.duplicate-select{display:flex;grid-template-columns:none;align-items:center;gap:6px;margin:0;color:var(--muted);font-size:12px}.duplicate-select input{margin:0}.duplicate-footer{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-top:14px;padding-top:13px;border-top:1px solid var(--line);color:var(--muted);font-size:12px}.duplicate-manage-note{margin:12px 0 0;color:var(--muted);font-size:12px}@media(max-width:650px){.duplicate-head-actions{align-items:flex-start;margin-top:8px}.duplicate-footer{align-items:flex-start;flex-direction:column}}


/* 2.1.1c recommendations + Trash */
.recommended-action{border-color:color-mix(in srgb,var(--accent) 70%,var(--line));font-weight:650}.recommended-badge{display:inline-block;margin:0 9px 8px;padding:3px 7px;border-radius:999px;background:color-mix(in srgb,var(--accent) 16%,var(--bg));color:var(--text);font-size:10px;font-weight:700}.trash{display:grid;gap:18px}.trash-toolbar{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px 14px;border:1px solid var(--line);border-radius:10px;background:var(--panel);color:var(--muted);font-size:12px}.trash-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px}.trash-tile{border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--panel)}.trash-image-button{display:block;width:100%;border:0;padding:0;background:transparent;cursor:pointer}.trash-image-button img{display:block;width:100%;aspect-ratio:1.25;object-fit:cover;background:var(--hover);filter:saturate(.75)}.trash-image-button:hover img,.trash-image-button:focus-visible img{filter:saturate(.9) brightness(.95)}.trash-body{display:grid;gap:3px;padding:9px 10px}.trash-body strong{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.trash-body span{font-size:11px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.trash-actions{display:flex;gap:8px;flex-wrap:wrap;padding:0 10px 10px}@media(max-width:650px){.trash-toolbar{align-items:flex-start;flex-direction:column}.trash-grid{grid-template-columns:repeat(2,1fr)}}

/* 2.1.2 scoped timelines */
.page-tools{display:flex;align-items:center;justify-content:flex-end;gap:10px;flex-wrap:wrap}.view-switch{display:inline-flex;border:1px solid var(--line);border-radius:9px;overflow:hidden;background:var(--panel)}.view-switch-button{border:0;border-right:1px solid var(--line);background:transparent;padding:7px 11px;cursor:pointer;font-size:12px}.view-switch-button:last-child{border-right:0}.view-switch-button:hover{background:var(--hover)}.view-switch-button.active{background:var(--hover);font-weight:700}.timeline-jump{max-width:190px;border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--text);padding:7px 28px 7px 9px;font-size:12px}.timeline-day{scroll-margin-top:86px}@media(max-width:650px){.page-head{align-items:flex-start}.page-tools{width:100%;justify-content:flex-start}.timeline-jump{max-width:100%;}.view-switch-button{min-height:38px}}

/* 2.1.3 right-side timeline scrubber */
.timeline-layout{display:block;min-width:0}.timeline-layout.has-rail{display:grid;grid-template-columns:minmax(0,1fr) 82px;gap:16px;align-items:start}.timeline-rail{position:sticky;top:88px;height:calc(100vh - 112px);min-height:310px;max-height:760px;display:flex;flex-direction:column;align-items:center;gap:7px;padding:2px 0 8px;color:var(--muted);user-select:none}.timeline-rail-all{border:0;background:transparent;color:var(--muted);border-radius:7px;padding:5px 8px;font-size:11px;cursor:pointer}.timeline-rail-all:hover,.timeline-rail-all.active{background:var(--hover);color:var(--text);font-weight:700}.timeline-rail-readout{height:18px;line-height:18px;color:var(--text);font-size:11px;font-weight:650;white-space:nowrap}.timeline-rail-track{position:relative;flex:1;width:76px;min-height:230px;outline:none;cursor:ns-resize;touch-action:none}.timeline-rail-track::before{content:"";position:absolute;top:0;bottom:0;right:13px;width:2px;border-radius:2px;background:var(--line)}.timeline-rail-track:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:6px}.timeline-rail-marks{position:absolute;inset:0}.timeline-rail-mark{position:absolute;right:8px;width:12px;height:12px;margin-top:-6px;border:2px solid var(--bg);border-radius:50%;padding:0;background:var(--muted);opacity:.42;cursor:pointer;z-index:2}.timeline-rail-mark:hover,.timeline-rail-mark.active{opacity:1;background:var(--accent);transform:scale(1.15)}.timeline-rail-year{position:absolute;right:27px;transform:translateY(-50%);border:0;background:transparent;color:var(--muted);padding:2px 3px;font-size:10px;line-height:1;cursor:pointer}.timeline-rail-year:hover{color:var(--text);font-weight:700}.timeline-rail-thumb{position:absolute;right:5px;width:18px;height:18px;margin-top:-9px;border:3px solid var(--bg);border-radius:50%;background:var(--accent);box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 55%,var(--line));pointer-events:none;z-index:4}.timeline-jump{display:none}.timeline-day{scroll-margin-top:86px}
@media(max-width:850px){.timeline-layout.has-rail{display:block}.timeline-rail{display:none!important}.timeline-jump:not(.hidden){display:block}.timeline-jump{max-width:100%}}
.asset .match-badge{position:absolute;left:7px;top:7px;max-width:calc(100% - 14px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:rgba(0,0,0,.72);color:#fff;border-radius:5px;padding:4px 7px;font-size:10px;font-weight:650;letter-spacing:.01em}

/* 2.4.2 face detection */
.face-asset{background:#111;min-height:120px;align-self:start}.face-asset img{object-fit:fill}.face-box{position:absolute;border:2px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,.75),0 1px 5px rgba(0,0,0,.45);pointer-events:none}.face-count-badge{position:absolute;right:7px;bottom:7px;background:rgba(0,0,0,.72);color:#fff;border-radius:12px;padding:4px 7px;font-size:11px;pointer-events:none}.face-asset:hover img,.face-asset:focus-visible img{transform:none}

.explore-progress{margin:-10px 0 22px;padding:10px 12px;border:1px solid var(--line);border-radius:10px;background:var(--panel)}.explore-progress-row{display:flex;justify-content:space-between;gap:16px;margin-bottom:7px;color:var(--muted);font-size:13px}.explore-progress-count{font-variant-numeric:tabular-nums;white-space:nowrap}.explore-progress-track{height:5px;overflow:hidden;border-radius:999px;background:var(--hover)}.explore-progress-bar{height:100%;width:0;background:var(--accent);border-radius:inherit;transition:width .18s ease}.explore-progress:not(.hidden) .explore-progress-bar{min-width:8%;animation:explore-progress-pulse .9s ease-in-out infinite alternate}@keyframes explore-progress-pulse{from{opacity:.62}to{opacity:1}}@media(prefers-reduced-motion:reduce){.explore-progress:not(.hidden) .explore-progress-bar{animation:none}}

/* 2.4.15 web upload */
.upload-button{border:1px solid var(--line);border-radius:8px;background:var(--panel);padding:7px 14px;cursor:pointer;font-size:13px;font-weight:650;white-space:nowrap}.upload-button:hover{background:var(--hover)}#upload-modal .dialog{width:min(520px,calc(100vw - 30px))}.dialog-actions{display:flex;gap:10px;margin-top:16px}.secondary{border:1px solid var(--line);border-radius:8px;padding:10px 16px;background:var(--bg);color:var(--text);cursor:pointer}.secondary:disabled,.primary:disabled{opacity:.5;cursor:default}.dropzone{margin-top:8px;border:2px dashed var(--line);border-radius:12px;padding:34px 18px;text-align:center;color:var(--muted);cursor:pointer;transition:border-color .15s,background .15s}.dropzone:hover,.dropzone:focus-visible{border-color:color-mix(in srgb,var(--accent) 55%,var(--line));background:var(--hover);outline:none}.dropzone.dragover{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,var(--bg));color:var(--text)}.dropzone-hint{margin:0;line-height:1.6}.dropzone-link{color:var(--accent);font-weight:650;text-decoration:underline}.upload-list{list-style:none;margin:14px 0 0;padding:0;max-height:260px;overflow:auto;display:grid;gap:6px}.upload-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--line);border-radius:8px;font-size:13px}.upload-item .up-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.upload-item .up-size{color:var(--muted);font-size:11px;white-space:nowrap}.upload-item .up-status{font-size:11px;font-weight:650;white-space:nowrap}.upload-item.pending .up-status{color:var(--muted)}.upload-item.busy .up-status{color:var(--accent)}.upload-item.done .up-status{color:#2b9348}.upload-item.failed{border-color:#c55}.upload-item.failed .up-status{color:#c33}

#edit-modal{z-index:70}

.map-view{height:calc(100vh - 130px);border-radius:12px;overflow:hidden}
.map-view .leaflet-popup-content{margin:8px}
.map-thumb{width:120px;height:auto;display:block;border-radius:6px;cursor:pointer}
.map-cap{font-size:12px;color:#333;margin-top:4px;max-width:120px}

.checkbox-row{display:flex;align-items:center;gap:8px;flex-direction:row!important}
.checkbox-row input{width:auto}

/* 2.5.10 tags view */
.tags-view{padding:4px}
.tags-toolbar{display:flex;gap:8px;margin-bottom:14px}
.tags-toolbar button{border:1px solid var(--line);border-radius:8px;background:var(--panel);padding:6px 14px;cursor:pointer;font-size:13px}
.tags-toolbar button.active{background:var(--accent);color:#fff;border-color:var(--accent)}
.tag-list{display:flex;flex-direction:column;gap:2px}
.tag-list .tag-row{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-radius:8px;cursor:pointer}
.tag-list .tag-row:hover{background:var(--hover)}
.tag-list .tag-count{color:var(--muted);font-size:12px;font-variant-numeric:tabular-nums}
.tag-cloud{display:flex;flex-wrap:wrap;gap:10px 16px;align-items:baseline;padding:8px}
.tag-cloud .tag-chip{cursor:pointer;color:var(--text);line-height:1.1}
.tag-cloud .tag-chip:hover{color:var(--accent);text-decoration:underline}

/* 2.5.12 bulk select */
.select-bar{display:inline-flex;gap:8px}
.asset.selected{outline:3px solid var(--accent);outline-offset:-3px}
.asset.selected::after{content:'✓';position:absolute;top:6px;right:6px;background:var(--accent);color:#fff;border-radius:50%;width:22px;height:22px;display:flex;align-items:center;justify-content:center;font-size:14px}
.asset{position:relative}

/* Crop mode (3.8) */
.crop-overlay { position:absolute; z-index:5; cursor:crosshair; touch-action:none; }
.crop-rect { position:absolute; border:2px solid #fff; box-shadow:0 0 0 9999px rgba(0,0,0,0.5); cursor:move; }
.crop-bar { position:absolute; bottom:16px; left:50%; transform:translateX(-50%); z-index:6;
  display:flex; gap:8px; background:rgba(0,0,0,0.7); padding:8px 10px; border-radius:8px; }
.crop-bar button { padding:6px 12px; border:none; border-radius:6px; cursor:pointer; font-size:13px; }
.crop-bar .crop-apply { background:#2d7d46; color:#fff; }
.crop-bar .crop-cancel { background:#555; color:#fff; }
.crop-bar .crop-revert { background:#7d2d2d; color:#fff; }

.crop-handle { position:absolute; width:16px; height:16px; background:#fff; border:2px solid #333; border-radius:50%; z-index:7; }
.crop-handle.nw { left:-9px; top:-9px; cursor:nwse-resize; }
.crop-handle.ne { right:-9px; top:-9px; cursor:nesw-resize; }
.crop-handle.sw { left:-9px; bottom:-9px; cursor:nesw-resize; }
.crop-handle.se { right:-9px; bottom:-9px; cursor:nwse-resize; }

.deleted-badge { position:absolute; left:7px; top:7px; background:#c0392b; color:#fff;
  border-radius:4px; padding:3px 6px; font-size:10px; font-weight:700; letter-spacing:.04em; z-index:2; }
.viewer-deleted-badge { background:#c0392b; color:#fff; border-radius:5px; padding:4px 9px;
  font-size:12px; font-weight:700; letter-spacing:.05em; margin-left:10px; }

.asset.dragging { opacity:.4; }
.asset { position:relative; }
/* Drop indicator: shrink the tiles on BOTH sides of the insertion point to
 * open an even, obvious gap with a bold bar.  A thin edge line gets buried
 * under the browser's drag ghost, so we make physical space and fill it. */
/* Insertion markers (layout-stable, no flutter).  Both tiles flanking the
 * drop gap get a bold bar on their facing edge + a bright inner edge glow. */
.asset.drop-before::before, .asset.drop-after::after {
  content:""; position:absolute; top:-6px; bottom:-6px; width:14px; border-radius:7px;
  background:#ffe000;
  box-shadow:0 0 18px 6px rgba(255,224,0,1), 0 0 0 3px rgba(0,0,0,0.7);
  z-index:30; pointer-events:none; }
.asset.drop-before::before { left:-9px; }
.asset.drop-after::after  { right:-9px; }
.asset.drop-before { box-shadow: inset 6px 0 0 -1px #ffe000; }
.asset.drop-after  { box-shadow: inset -6px 0 0 -1px #ffe000; }
.asset[draggable=true] { cursor:grab; }

/* Admin / album settings (step 4) */
.dialog-wide { max-width:640px; width:90vw; }
.checkline { display:flex; align-items:center; gap:8px; margin:8px 0; }
.admin-user-row { display:flex; align-items:center; gap:10px; padding:5px 0; border-bottom:1px solid var(--border,#333); flex-wrap:wrap; }
.admin-user-name { min-width:120px; font-weight:600; }
.admin-user-row label { display:flex; align-items:center; gap:3px; font-size:13px; }
.access-add { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:10px; }
.access-add-col { flex-direction:row; }
.access-add label { display:flex; align-items:center; gap:3px; font-size:13px; }
.verbrow { display:flex; gap:8px; flex-wrap:wrap; }
.danger { background:#7d2d2d; color:#fff; border:none; border-radius:6px; padding:8px 14px; cursor:pointer; }
.danger-sm { background:#7d2d2d; color:#fff; border:none; border-radius:4px; padding:2px 8px; cursor:pointer; }
#as-access-section h3, #admin-modal h3 { margin:14px 0 6px; font-size:15px; }

/* Face box overlay in People view */
.face-box {
  position: absolute;
  border: 2px solid #ffd400;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.5), 0 0 6px rgba(255,212,0,0.6);
  border-radius: 3px;
  pointer-events: none;
  box-sizing: border-box;
}

/* When a tile/cover shows a face box, the image must be object-fit:contain so
 * the box (positioned in full-image fractions) aligns with the displayed pixels
 * (cover-crop would shift it). */
.asset:has(.face-box) img { object-fit: contain; }
.album-cover:has(.face-box) img { object-fit: contain; }

/* "Not this person" split action on person-view tiles */
.split-badge {
  position: absolute; left: 6px; top: 6px; z-index: 3;
  background: rgba(192,57,43,0.92); color: #fff;
  border-radius: 5px; padding: 3px 7px; font-size: 11px; font-weight: 600;
  cursor: pointer; opacity: 0; transition: opacity .12s;
}
.asset:hover .split-badge, .split-badge:focus { opacity: 1; }

.people-filter{display:flex;gap:8px;margin:0 0 18px}
.people-filter-btn{border:1px solid var(--line);background:var(--bg);color:var(--text);border-radius:16px;padding:5px 14px;font-size:13px;cursor:pointer}
.people-filter-btn.active{background:var(--accent);color:#fff;border-color:var(--accent)}

.geo-row{display:flex;align-items:center;gap:8px;margin:12px 0;flex-wrap:wrap}
.geo-row .geo-label{font-size:13px;color:var(--muted);width:100%}
.geo-row input{flex:1;min-width:90px;padding:8px 10px;border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--text)}
.geo-row button{padding:8px 12px;border:1px solid var(--line);background:var(--bg);color:var(--text);border-radius:8px;cursor:pointer}

/* Merge person picker */
#merge-modal .dialog{width:min(420px,calc(100vw - 30px))}
#merge-filter{width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--text);margin:6px 0 10px}
.merge-list{max-height:320px;overflow:auto;display:grid;gap:4px}
.merge-row{display:flex;align-items:center;justify-content:space-between;gap:10px;border:1px solid var(--line);background:var(--bg);color:var(--text);border-radius:8px;padding:9px 12px;cursor:pointer;text-align:left}
.merge-row:hover{background:var(--hover)}
.merge-row-name{font-weight:600}
.merge-row-meta{color:var(--muted);font-size:12px;white-space:nowrap}
.merge-none{color:var(--muted);padding:12px;text-align:center}

/* PDF/document viewer */
.viewer-doc { width: 80vw; height: 85vh; border: none; background: #fff; border-radius: 6px; }

/* album card: name (h3), description (.album-desc), details (.album-details) */
.album-card .album-desc { color: var(--text); font-size: 13px; opacity: 0.85; margin: 2px 2px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.album-card .album-details { color: var(--muted); font-size: 12px; margin: 2px 2px 0; }
/* album view header: description under the title, smaller/muted (uses .page-head p already, but ensure wrap) */
.page-head p { max-width: 70ch; }

/* Viewer caption (under the image): subject + smaller location/date */
.viewer-caption { position: absolute; left: 0; right: 0; bottom: 0; padding: 14px 18px 16px;
  background: linear-gradient(to top, rgba(0,0,0,0.72), rgba(0,0,0,0) ); color: #fff;
  text-align: center; pointer-events: none; z-index: 5; }
.viewer-caption .cap-subject { font-size: 18px; font-weight: 600; text-shadow: 0 1px 3px rgba(0,0,0,.6); }
.viewer-caption .cap-meta { font-size: 13px; opacity: 0.85; margin-top: 2px; text-shadow: 0 1px 3px rgba(0,0,0,.6); }
/* Hover description overlay */
.media-desc { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  max-width: 70%; max-height: 60%; overflow: auto; background: rgba(0,0,0,0.6); color: #fff;
  padding: 16px 20px; border-radius: 10px; font-size: 15px; line-height: 1.45;
  z-index: 6; pointer-events: none; backdrop-filter: blur(2px); white-space: pre-wrap; }

/* Loading spinner — shown while a view is fetching/rendering. */
@keyframes pa-spin { to { transform: rotate(360deg); } }
.timeline.loading, .album-grid.loading { position: relative; min-height: 160px; }
.timeline.loading::after, .album-grid.loading::after {
  content: ""; position: absolute; left: 50%; top: 80px; width: 40px; height: 40px;
  margin-left: -20px; border: 4px solid var(--line); border-top-color: var(--accent);
  border-radius: 50%; animation: pa-spin 0.8s linear infinite; z-index: 2;
}
/* Global busy overlay (for actions not tied to the grid) */
#busy-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.15); z-index: 200;
  display: grid; place-items: center; }
#busy-overlay .spin { width: 48px; height: 48px; border: 5px solid rgba(255,255,255,0.5);
  border-top-color: var(--accent); border-radius: 50%; animation: pa-spin 0.8s linear infinite; }
body.busy { cursor: progress; }

/* Per-tile placeholder pulse until the thumbnail image loads */
@keyframes pa-pulse { 0%{opacity:.4} 50%{opacity:.7} 100%{opacity:.4} }
.asset.img-loading, .album-cover.img-loading { animation: pa-pulse 1.2s ease-in-out infinite; }

/* Sidebar nav count badges */
.nav { width: 100%; }
.nav .nav-count { margin-left: auto; font-size: 12px; color: var(--muted); font-weight: 500;
  background: var(--hover); border-radius: 10px; padding: 1px 8px; min-width: 20px; text-align: center; }
.nav.active .nav-count { background: var(--bg); }

/* Ignore badge — top-right on a person tile; drops the face from the People pool */
.ignore-badge {
  position: absolute; right: 6px; top: 6px; z-index: 3;
  background: rgba(60,60,60,0.92); color: #fff;
  border-radius: 5px; padding: 3px 7px; font-size: 11px; font-weight: 600;
  cursor: pointer; opacity: 0; transition: opacity .12s;
}
.asset:hover .ignore-badge, .ignore-badge:focus { opacity: 1; }

/* Sticky, collapsible page head (album + person views).  When scrolled, the
   title/subtitle/tools condense to a single fixed line under the top bar. */
.content.sticky-head .page-head {
  position: sticky; top: 70px; z-index: 12;
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(8px);
  margin-left: -30px; margin-right: -30px; padding: 10px 30px;
  border-bottom: 1px solid transparent;
  transition: padding .12s ease, border-color .12s;
}
.content.sticky-head .page-head.collapsed {
  align-items: center;
  padding-top: 6px; padding-bottom: 6px;
  border-bottom-color: var(--line);
}
.content.sticky-head .page-head.collapsed h1 { font-size: 17px; margin: 0; }
.content.sticky-head .page-head.collapsed #subtitle { display: none; }
.content.sticky-head .page-head.collapsed .back { padding: 4px 6px; font-size: 13px; }
.content.sticky-head .page-head.collapsed .page-tools { gap: 6px; }
@media (max-width: 850px){ .content.sticky-head .page-head { top: 56px; } }

/* Tighter top bar + search field */
.topbar { height: 54px; }
.search-wrap { padding: 6px 13px; }
.search-wrap input { font-size: 14px; }
.content.sticky-head .page-head { top: 54px; }
@media (max-width: 850px){ .topbar { height: 50px; } .content.sticky-head .page-head { top: 50px; } }

/* "Set cover" badge — bottom-left on a person tile */
.cover-badge {
  position: absolute; left: 6px; bottom: 6px; z-index: 3;
  background: rgba(255,107,53,0.94); color: #fff;
  border-radius: 5px; padding: 3px 7px; font-size: 11px; font-weight: 600;
  cursor: pointer; opacity: 0; transition: opacity .12s;
}
.asset:hover .cover-badge, .cover-badge:focus { opacity: 1; }

/* Person view: while a selection is active, hide the per-tile hover badges
   (split/ignore/cover) — actions come from the top action bar instead. */
.timeline.has-selection .split-badge,
.timeline.has-selection .ignore-badge,
.timeline.has-selection .cover-badge { display: none !important; }
/* Selected tile highlight (person grid) */
.asset.selected { outline: 3px solid var(--accent); outline-offset: -3px; }

/* Map popup: single or multi-photo strip */
.map-popup .map-cap { font-weight: 600; margin-bottom: 6px; max-width: none; }
.map-strip.multi { display: grid; grid-template-columns: repeat(3, 72px); gap: 5px;
  max-height: 240px; overflow-y: auto; }
.map-strip.multi .map-thumb { width: 72px; height: 72px; object-fit: cover; }
.map-thumb { cursor: pointer; }
.map-thumb:hover { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Leaflet's internal panes/controls/popups use z-index up to ~1000, which
   sat above the viewer overlay (z-index 60) — so a photo opened from a map
   marker rendered UNDER the map.  Lift the viewer and its modals above Leaflet. */
.viewer { z-index: 2000; }
#edit-modal { z-index: 2100; }
.modal { z-index: 2100; }
.toast { z-index: 2200; }
#busy-overlay { z-index: 2300; }

/* Viewer "show people" face overlay */
.face-overlay { position:absolute; z-index:5; border:2px solid #ffd400;
  border-radius:3px; box-shadow:0 0 0 1px rgba(0,0,0,.5); pointer-events:auto; }
.face-overlay.named { border-color:#4ade80; }
.face-overlay.unknown { border-color:#ffd400; }
.face-overlay.ignored { border-color:#888; opacity:.6; }
.face-overlay.clickable { cursor:pointer; }
.face-overlay.clickable:hover { box-shadow:0 0 0 2px #fff, 0 0 10px rgba(0,0,0,.6); }
.face-overlay-label { position:absolute; left:0; bottom:100%; margin-bottom:2px;
  background:rgba(0,0,0,.82); color:#fff; font-size:12px; padding:2px 6px;
  border-radius:4px; white-space:nowrap; opacity:0; transition:opacity .1s;
  pointer-events:none; }
.face-overlay:hover .face-overlay-label { opacity:1; }
#viewer-people.active { color:#4ade80; }

/* Flash-highlight a tile (e.g. the source photo when opening a person) */
.asset.flash-highlight { outline: 4px solid var(--accent); outline-offset: -4px;
  animation: pa-flash 2.6s ease-out; z-index: 2; }
@keyframes pa-flash {
  0%,15% { box-shadow: 0 0 0 4px var(--accent), 0 0 24px 6px rgba(255,107,53,.9); }
  100% { box-shadow: 0 0 0 4px rgba(255,107,53,0); }
}

/* Spinner while the full-size viewer media loads */
.media-spinner { position:absolute; top:50%; left:50%; width:52px; height:52px;
  margin:-26px 0 0 -26px; border:5px solid rgba(255,255,255,.22);
  border-top-color:#fff; border-radius:50%; animation:pa-spin .8s linear infinite;
  z-index:3; pointer-events:none; }

/* Add-face manual box mode */
.media.adding-face { cursor: crosshair; }
.media.adding-face img { cursor: crosshair; }
.face-rubber { position:absolute; z-index:6; border:2px dashed #4ade80;
  background:rgba(74,222,128,.15); pointer-events:none; }
#viewer-addface.active { color:#4ade80; }

/* Remove-face ✕ on an overlay box */
.face-overlay-del { position:absolute; top:-11px; left:100%; margin-left:3px; width:18px; height:18px;
  line-height:16px; text-align:center; border-radius:50%; background:#e11d48; color:#fff;
  font-size:11px; cursor:pointer; opacity:0; transition:opacity .1s; z-index:8;
  box-shadow:0 1px 4px rgba(0,0,0,.6); }
.face-overlay:hover .face-overlay-del { opacity:1; }
.face-overlay-del:hover { background:#f43f5e; }


/* DFB (delete face box) badge — bottom-right of a person tile */
.dfb-badge {
  position: absolute; right: 6px; bottom: 6px; z-index: 3;
  background: rgba(150,30,30,0.92); color: #fff;
  border-radius: 5px; padding: 3px 7px; font-size: 11px; font-weight: 600;
  cursor: pointer; opacity: 0; transition: opacity .12s;
}
.asset:hover .dfb-badge, .dfb-badge:focus { opacity: 1; }
.timeline.has-selection .dfb-badge { display: none !important; }

/* Albums LIST layout (toggle from the albums page) */
.album-grid.list-layout { display: flex; flex-direction: column; gap: 8px; max-width: 900px; }
.album-grid.list-layout .album-card {
  display: grid; grid-template-columns: 96px 1fr; grid-auto-rows: min-content;
  column-gap: 14px; align-content: center; align-items: start;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px;
}
.album-grid.list-layout .album-card:hover { background: var(--hover); }
.album-grid.list-layout .album-cover { grid-column: 1; grid-row: 1 / 4; align-self: center;
  width: 96px; aspect-ratio: 1.35; border-radius: 8px; }
.album-grid.list-layout .album-card h3 { grid-column: 2; margin: 2px 0 2px; font-size: 15px; }
.album-grid.list-layout .album-card p  { grid-column: 2; white-space: normal; color: var(--muted); }

/* Album "completed" checkbox + state */
.album-card { position: relative; }
.album-done { position: absolute; top: 6px; left: 6px; z-index: 4;
  background: rgba(0,0,0,.55); color: #fff; font-size: 11px; padding: 3px 7px;
  border-radius: 6px; cursor: pointer; display: flex; align-items: center; gap: 4px;
  opacity: 0; transition: opacity .12s; }
.album-card:hover .album-done, .album-done input:focus { opacity: 1; }
.album-completed .album-done { opacity: 1; background: rgba(22,140,60,.9); }
.album-completed .album-cover { outline: 3px solid #16a34a; outline-offset: -3px; }
.album-completed .album-cover::after { content: "✓"; position: absolute; top: 6px; right: 8px;
  color: #fff; background: #16a34a; width: 22px; height: 22px; line-height: 22px;
  text-align: center; border-radius: 50%; font-weight: 700; }
/* list layout: checkbox sits in column 2, right-aligned, always visible */
.album-grid.list-layout .album-done { position: static; opacity: 1;
  grid-column: 2; justify-self: end; background: transparent; color: var(--muted); }
.album-grid.list-layout .album-completed .album-done { color: #16a34a; }
.album-grid.list-layout .album-completed .album-cover::after { top: 4px; right: 4px; width:18px; height:18px; line-height:18px; }

/* When scrolling a card/tile to the top via scrollIntoView, keep it below the
   fixed top bar + collapsed page-head (which overlay the top of the scroll area). */
.content.sticky-head .asset,
.content.sticky-head .album-card { scroll-margin-top: 104px; }
@media (max-width: 850px){
  .content.sticky-head .asset,
  .content.sticky-head .album-card { scroll-margin-top: 96px; }
}

/* Face-count badge (Group photos view) */
.facecount-badge { position:absolute; left:6px; top:6px; z-index:3;
  background:rgba(0,0,0,.72); color:#fff; border-radius:12px; padding:3px 8px;
  font-size:12px; font-weight:600; pointer-events:none; }
