/* cheapshots – plain CSS, no build step.
   Colours: Cheap Shots design (teal, coral, mustard on cream; dark teal-grey
   at night). Light and dark follow the system unless the viewer chose one
   with the switch in the top bar (theme.js sets data-theme on <html>). Every
   colour that differs between the two lives in the tokens below, so dark
   mode is decided in these three blocks only. Text colours meet WCAG AA. */

@font-face { font-family: "Bowlby One"; font-weight: 400; font-display: swap;
  src: url("fonts/bowlby-one-400.woff2") format("woff2"); }
@font-face { font-family: "Atkinson Hyperlegible"; font-weight: 400; font-display: swap;
  src: url("fonts/atkinson-hyperlegible-400.woff2") format("woff2"); }
@font-face { font-family: "Atkinson Hyperlegible"; font-weight: 700; font-display: swap;
  src: url("fonts/atkinson-hyperlegible-700.woff2") format("woff2"); }
@font-face { font-family: "Atkinson Hyperlegible"; font-weight: 400; font-style: italic; font-display: swap;
  src: url("fonts/atkinson-hyperlegible-400-italic.woff2") format("woff2"); }
@font-face { font-family: "Atkinson Hyperlegible"; font-weight: 700; font-style: italic; font-display: swap;
  src: url("fonts/atkinson-hyperlegible-700-italic.woff2") format("woff2"); }

:root {
  --bg: #FDF0D5;
  --panel: #FFF8E8;
  --text: #1F2A2A;
  --muted: #4B5A58;
  --line: #E6D3A8;
  --accent: #17695F;
  --accent-soft: #E3E9D6;
  --on-accent: #FFFFFF;
  --stage: #141B1B;
  /* Messages and states. A "-soft" background always goes with its "-ink". */
  --danger: #B8432B;
  --danger-bg: #B8432B;
  --on-danger: #FFFFFF;
  --fav: #B8432B;
  --star: #9A6B12;
  --teal-soft: #E3E9D6; --teal-ink: #17695F;
  --mustard-soft: #F8E6B0; --mustard-ink: #6E510C;
  --coral-soft: #F7DCCB; --coral-ink: #8F3420;
  --slate-soft: #E1E6E2; --slate-ink: #375669;
  --slate: #4A7189;
  --keep: #17695F; --keep-soft: #E3E9D6; --drop: #B8432B; --diff: #F8E6B0; --on-keep: #FFFFFF;
  --logo-light: block; --logo-dark: none;
  color-scheme: light;
  /* The same on both themes: over photos and on the always dark stage. */
  --coral: #E76F51;
  --mustard: #E9C46A;
  --f-head: "Bowlby One", "Arial Black", sans-serif;
  --f-body: "Atkinson Hyperlegible", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-family: var(--f-body);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  --bg: #1F2A2A;
  --panel: #283635;
  --text: #FDF0D5;
  --muted: #C9C2AE;
  --line: #3C4D4B;
  --accent: #5BB5A7;
  --accent-soft: #2E4A45;
  --on-accent: #1F2A2A;
  --stage: #111717;
  --danger: #F08A70;
  --fav: #E76F51;
  --star: #E9C46A;
  --teal-soft: #1E3D38; --teal-ink: #8FD0C4;
  --mustard-soft: #3D3418; --mustard-ink: #E9C46A;
  --coral-soft: #45291F; --coral-ink: #F08A70;
  --slate-soft: #25343C; --slate-ink: #A9C3D3;
  --keep: #5BB5A7; --keep-soft: #1E3D38; --drop: #F08A70; --diff: #3D3418; --on-keep: #1F2A2A;
  --logo-light: none; --logo-dark: block;
  color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #1F2A2A;
  --panel: #283635;
  --text: #FDF0D5;
  --muted: #C9C2AE;
  --line: #3C4D4B;
  --accent: #5BB5A7;
  --accent-soft: #2E4A45;
  --on-accent: #1F2A2A;
  --stage: #111717;
  --danger: #F08A70;
  --fav: #E76F51;
  --star: #E9C46A;
  --teal-soft: #1E3D38; --teal-ink: #8FD0C4;
  --mustard-soft: #3D3418; --mustard-ink: #E9C46A;
  --coral-soft: #45291F; --coral-ink: #F08A70;
  --slate-soft: #25343C; --slate-ink: #A9C3D3;
  --keep: #5BB5A7; --keep-soft: #1E3D38; --drop: #F08A70; --diff: #3D3418; --on-keep: #1F2A2A;
  --logo-light: none; --logo-dark: block;
  color-scheme: dark;
}

* { box-sizing: border-box; }
body { margin: 0; background: var(--bg); color: var(--text); font-size: 15px; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
code { background: var(--panel); padding: 1px 6px; border-radius: 6px; }
button, input, select, textarea { font-family: inherit; }
/* Headings: Bowlby One for page titles and the month names; names chosen by
   people (photo titles, albums, people, places) in Atkinson Bold, as Bowlby
   is too heavy for long or small text. Bowlby has one weight only. */
h1 { font-family: var(--f-head); font-weight: 400; line-height: 1.15; letter-spacing: .01em; }
.info h1, .album-head h1, .person-head h1, h1.crumbs {
  font-family: var(--f-body); font-weight: 700; letter-spacing: 0;
}
/* The light or the dark logo, whichever fits the theme. */
.logo-light { display: var(--logo-light) !important; }
.logo-dark { display: var(--logo-dark) !important; }

/* Top bar */
.topbar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: 24px;
  padding: 12px 24px; background: var(--panel); border-bottom: 1px solid var(--line);
}
.brand { display: block; line-height: 0; }
.brand img { height: 30px; width: auto; }
img.mark { display: none !important; height: 36px; border-radius: 8px; }
@media (max-width: 760px) {
  .brand .word { display: none !important; }
  .brand .mark.logo-light { display: var(--logo-light) !important; }
  .brand .mark.logo-dark { display: var(--logo-dark) !important; }
}
.search { flex: 1; max-width: 720px; }
.search input {
  width: 100%; padding: 10px 16px; font-size: 15px; color: var(--text);
  background: var(--bg); border: 1px solid var(--line); border-radius: 999px;
}
.search input { text-overflow: ellipsis; }
.search input:focus { outline: 2px solid var(--accent); border-color: transparent; }

/* Overview */
.layout { display: grid; grid-template-columns: 220px 1fr; min-height: 80vh; }
.facets {
  display: flex; flex-direction: column;
  padding: 20px 16px; border-right: 1px solid var(--line);
  /* Stays in view while scrolling, so the storage display is always visible. */
  position: sticky; top: 65px; align-self: start;
  height: calc(100vh - 65px); overflow-y: auto;
}
/* Storage display at the bottom of the sidebar */
.storage { margin-top: auto; padding: 24px 8px 0; font-size: 13px; }
.facets .storage h2 { margin: 0 0 8px; }
.storage p { margin: 6px 0 0; }
.storage .muted { color: var(--muted); }
.meter { height: 6px; border-radius: 999px; background: var(--line); overflow: hidden; }
.meter span { display: block; height: 100%; background: var(--accent); }
/* Space runs out (storage.py: Usage.level): mustard from 80 %, red when full. */
.storage.warn .meter span { background: var(--mustard); }
.storage.full .meter span { background: var(--danger-bg); }
.storage .warning { font-weight: 600; }
.storage.warn .warning { color: var(--mustard-ink); }
.storage.full .warning { color: var(--danger); }
dd.storage { margin-top: 0; padding: 0; font-size: inherit; flex-wrap: wrap; }
dd.storage .meter { flex: 0 0 100%; width: 100%; max-width: 320px; margin: 4px 0 2px; }
dd.storage .warning { display: block; flex: 0 0 100%; }
/* The warning above the gallery and on "Hochladen" (_storage.html). */
.notice.storage-alert { display: flex; gap: 10px; align-items: flex-start; margin: 0 0 16px; }
.notice.storage-alert svg {
  flex: none; width: 20px; height: 20px; margin-top: 1px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.notice.storage-alert a { color: inherit; text-decoration: underline; font-weight: 600; white-space: nowrap; }
.notice.storage-alert.warn { background: var(--mustard-soft); color: var(--mustard-ink); }
.notice.storage-alert.full { background: var(--coral-soft); color: var(--coral-ink); }
.facets h2 {
  margin: 20px 8px 6px; font-size: 12px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted);
}
.facets ul { list-style: none; margin: 0; padding: 0; }
.facets li a {
  display: flex; justify-content: space-between; gap: 8px;
  padding: 5px 8px; border-radius: 8px; color: var(--text);
}
.facets li a:hover { background: var(--accent-soft); text-decoration: none; }
.reset { display: block; padding: 6px 8px; font-size: 14px; }
.facets-head { display: flex; align-items: center; gap: 8px; min-height: 30px; }
.facets-head .reset { margin-right: auto; white-space: nowrap; }
.icon.fold-all {
  width: 30px; height: 30px; margin-left: auto;
  color: var(--muted); background: none;
}
.icon.fold-all:hover { background: var(--accent-soft); color: var(--text); }
.icon.fold-all svg { width: 16px; height: 16px; }
/* Sidebar sections fold (<details>); folded, the head shows what is chosen. */
.facet summary {
  display: flex; align-items: center; gap: 6px; list-style: none;
  margin: 14px 0 4px; padding: 4px 8px; border-radius: 8px; cursor: pointer;
}
.facet summary::-webkit-details-marker { display: none; }
.facet summary:hover { background: var(--accent-soft); }
.facets .facet h2 { margin: 0; }
.facet .chevron {
  width: 14px; height: 14px; margin-left: auto; flex: none; fill: none;
  stroke: var(--muted); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .15s;
}
.facet:not([open]) .chevron { transform: rotate(-90deg); }
.facet .pills { display: none; gap: 4px; flex-wrap: wrap; min-width: 0; }
.facet:not([open]) .pills { display: flex; }
.facet .pill {
  padding: 0 7px; border-radius: 999px; background: var(--accent); color: var(--bg);
  font-size: 12px; font-weight: 600; line-height: 18px; white-space: nowrap;
}
/* A chosen value: a click removes the filter again. */
.facets li a.chosen { background: var(--accent-soft); font-weight: 600; }
.facets li a.chosen .count { color: var(--accent); font-size: 16px; line-height: 1; }
.facets ul.collections { margin-bottom: 8px; }
.collections .label { display: flex; align-items: center; gap: 8px; }
.collections svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.collections .heart svg { fill: var(--fav); stroke: var(--fav); }
.collections .trash svg { stroke: var(--danger); }
.collections .pencil svg { stroke: var(--accent); }
.facets li a.current { background: var(--accent-soft); font-weight: 600; }
.count { color: var(--muted); font-size: 13px; font-weight: 400; }

.content { padding: 16px 24px 40px; }
.summary { color: var(--muted); margin: 4px 0 8px; }
.summary-bar { display: flex; align-items: center; justify-content: space-between; }
.view-actions { display: flex; gap: 8px; }
.view-actions .icon { color: var(--text); background: var(--panel); }
.view-actions .icon:hover { background: var(--accent-soft); }
/* Sidebar switch (#sidebar, checked = not the default): on wide screens it
   hides the sidebar, on phones it opens the sidebar as a drawer over the
   photos. Two labels switch it. On wide screens the one at the top of the
   sidebar hides it, and only then does the one in the top bar appear, just
   before the logo, so that the logo lines up with the sidebar. On phones
   the top bar one opens the drawer and the sidebar one closes it. */
.sidebar-state { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.icon.sidebar-toggle { position: relative; flex: none; color: var(--text); background: var(--panel); }
.icon.sidebar-toggle:hover { background: var(--accent-soft); }
body:has(#sidebar:focus-visible) .sidebar-toggle { outline: 2px solid var(--accent); }
.sidebar-toggle.alert::after {
  content: ""; position: absolute; top: 5px; right: 5px; width: 9px; height: 9px;
  border-radius: 50%; background: var(--danger-bg); border: 2px solid var(--panel);
}
.sidebar-toggle.alert.warn::after { background: var(--mustard); }
/* The top bar one sits close to the logo. */
.icon.open-sidebar { margin: 0 -16px 0 -12px; }
.facets-head .close-sidebar { width: 30px; height: 30px; margin: 0 0 0 auto; background: none; }
.facets-head .fold-all + .close-sidebar { margin-left: 0; }
/* "Suche zurücksetzen" and both icons do not fit into one row of the
   sidebar: the link goes below them. */
.facets-head { flex: none; flex-wrap: wrap; gap: 4px; }
.facets-head .reset { order: 1; flex-basis: 100%; }
.facets-head .close-sidebar svg { width: 18px; height: 18px; }
.backdrop { display: none; }
@media (min-width: 761px) {
  body:not(:has(#sidebar:checked)) .open-sidebar { display: none; }
  body:has(#sidebar:checked) .layout { grid-template-columns: 1fr; }
  body:has(#sidebar:checked) .facets { display: none; }
}
/* Switch between gallery and map; the current view is not a link. */
.view-switch { display: flex; gap: 2px; padding: 3px; border-radius: 999px; background: var(--panel); }
.view-actions .view-switch .icon { width: 34px; height: 34px; background: transparent; color: var(--muted); }
.view-actions .view-switch .icon:hover { background: var(--accent-soft); }
.view-actions .view-switch .current,
.view-actions .view-switch label:has(input:checked) {
  background: var(--bg); color: var(--text); box-shadow: 0 1px 3px rgba(0, 0, 0, .15);
}
.view-switch input { position: absolute; opacity: 0; pointer-events: none; }
.view-switch label:has(input:focus-visible) { outline: 2px solid var(--accent); }

/* Map view: the map stays in place, the photos of its area scroll beside it. */
.mapview { display: grid; grid-template-columns: 3fr 2fr; gap: 16px; align-items: start; }
.photo-map {
  position: sticky; top: 81px; height: calc(100vh - 97px);
  border-radius: 12px; background: var(--panel);
}
.map-photos .grid { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); }
.map-photos .month:first-child h2 { margin-top: 0; }
.summary .muted { color: var(--muted); }
.map-group { position: relative; }
/* Leaflet sizes marker images itself; this selector is more specific. */
.photo-map .leaflet-marker-pane .map-group img {
  width: 52px; height: 52px; object-fit: cover; display: block;
  border: 3px solid #fff; border-radius: 10px; box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
}
.map-group span {
  position: absolute; top: -10px; right: -12px; min-width: 22px; padding: 2px 6px;
  border-radius: 999px; background: var(--accent); color: var(--on-accent);
  font: 600 12px/18px system-ui, sans-serif; text-align: center;
}
.position {
  position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%); margin: 0;
  padding: 6px 14px; border-radius: 999px; background: rgba(0, 0, 0, .6); color: #fff; font-size: 13px;
}

/* Second view: photos in their aspect ratio. layout.js scales each row to
   the full width (never above --row-height); without JavaScript the height
   stays fixed and rows end unevenly on the right. Nothing is cropped. */
.content { --row-height: 220px; }
.content:has(#justified:checked) .grid { display: flex; flex-wrap: wrap; }
.content:has(#justified:checked) .tile {
  aspect-ratio: auto; height: var(--row-height);
  flex: 0 0 auto; width: min(100%, calc(var(--ratio) * var(--row-height)));
}
/* Places above the gallery (_places.html): crumbs and the next level as
   cards; the sidebar's place tree shows the same filter. */
.place-bar { margin: 4px 0 18px; padding: 12px 14px 14px; border-radius: 12px; background: var(--panel); }
.place-bar-head { display: flex; align-items: center; gap: 10px; }
.crumbs {
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; flex: 1; min-width: 0;
  margin: 0; font-size: 18px; font-weight: 650;
}
.crumbs a { font-weight: 400; }
.crumbs .sep { color: var(--muted); font-weight: 400; }
.place-bar .icon.close-bar { width: 30px; height: 30px; flex: none; background: none; color: var(--muted); }
.place-bar .icon.close-bar:hover { background: var(--accent-soft); color: var(--text); }
.place-bar .icon.close-bar svg { width: 16px; height: 16px; }
.place-bar .level { color: var(--muted); font-size: 13px; margin: 10px 0 8px; }
.place-bar .cards { display: grid; gap: 12px 10px; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.place-bar .card { display: flex; flex-direction: column; gap: 4px; min-width: 0; color: var(--text); }
.place-bar .card:hover { text-decoration: none; }
.place-bar .cover {
  position: relative; aspect-ratio: 4 / 3; border-radius: 10px; overflow: hidden; background: var(--line);
}
.place-bar .cover img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .15s; }
.place-bar .card:hover .cover img { transform: scale(1.04); }
.place-bar .cover .n {
  position: absolute; right: 6px; bottom: 6px; padding: 1px 7px; border-radius: 999px;
  background: rgba(0, 0, 0, .55); color: #fff; font-size: 12px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.place-bar .name { font-weight: 600; font-size: 14px; line-height: 1.25; overflow-wrap: anywhere; }
.place-bar .meta { color: var(--muted); font-size: 12px; margin-top: -3px; }
.place-bar .card.current .cover { outline: 3px solid var(--accent); outline-offset: -3px; }
.place-bar .card.current .name { color: var(--accent); }
.place-bar .card:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.place-bar .card.extra { display: none; }
.place-bar:has(#more-places:checked) .card.extra { display: flex; }
.more-places { display: inline-block; margin-top: 10px; color: var(--accent); font-size: 13px; cursor: pointer; }
.more-places .hide, .place-bar:has(#more-places:checked) .more-places .show { display: none; }
.place-bar:has(#more-places:checked) .more-places .hide { display: inline; }
.more-places-switch { position: absolute; opacity: 0; pointer-events: none; }
/* Phones: the cards as one row to swipe through; with a place chosen only
   that one, the others come back one level up (the crumbs, ⇧ P). */
@media (max-width: 760px) {
  .place-bar .cards {
    display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x proximity;
    margin: 0 -14px; padding: 0 14px 4px; scroll-padding: 0 14px;
  }
  .place-bar .card, .place-bar .card.extra { display: flex; flex: none; width: 130px; scroll-snap-align: start; }
  .place-bar .cards.has-current .card:not(.current) { display: none; }
  .place-bar .more-places { display: none; }
}
.collections .pin svg { stroke: var(--accent); }
/* The sidebar's place tree: states and cities below their country. */
.facets li.depth-1 a { padding-left: 22px; }
.facets li.depth-2 a { padding-left: 36px; }
.month h2 { font-family: var(--f-head); font-size: 20px; font-weight: 400; letter-spacing: .01em; margin: 24px 0 10px; }
.grid {
  display: grid; gap: 4px;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.tile {
  display: block; aspect-ratio: 1; overflow: hidden; background: var(--panel);
  scroll-margin-top: 90px; /* keep a tile reached by #anchor below the top bar */
}
.tile img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .15s;
}
.tile:hover img { transform: scale(1.04); }
.more {
  display: inline-block; margin-top: 24px; padding: 8px 18px;
  border: 1px solid var(--line); border-radius: 999px;
}
.toolbar { margin: 4px 0 8px; display: flex; flex-wrap: wrap; gap: 8px; }
.toolbar form { display: contents; }
.button {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 16px;
  font: inherit; color: var(--text); background: var(--panel);
  border: 1px solid var(--line); border-radius: 999px; cursor: pointer;
}
.button:hover { text-decoration: none; border-color: var(--muted); }
.button.danger { color: var(--on-danger); background: var(--danger-bg); border-color: var(--danger-bg); }
.button svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.notice {
  padding: 10px 14px; border-radius: 10px; background: var(--accent-soft);
}
.confirm { max-width: 900px; }
.confirm .buttons { display: flex; gap: 12px; margin: 20px 0; }
/* Progress of a long action (job.html). */
.job .job-state { font-size: 17px; }
/* Drawn by hand: browsers show a native bar in pale blue or grey. */
.job .job-bar {
  appearance: none; width: 100%; max-width: 560px; height: 14px;
  border: 1px solid var(--accent); border-radius: 7px; overflow: hidden;
  background: var(--accent-soft); color: var(--accent);
}
.job .job-bar::-webkit-progress-bar { background: var(--accent-soft); }
.job .job-bar::-webkit-progress-value { background: var(--accent); }
.job .job-bar::-moz-progress-bar { background: var(--accent); }
.job .muted { color: var(--muted); }
.job .job-file code { font-size: 13px; }
.changes { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.changes li { display: flex; gap: 12px; align-items: center; }
.changes img { width: 64px; height: 64px; object-fit: cover; border-radius: 8px; flex: none; }
.changes p { margin: 4px 0 0; display: flex; flex-wrap: wrap; gap: 6px; font-size: 13px; }
.changes span { padding: 1px 8px; border-radius: 999px; }
.changes .added { background: var(--teal-soft); color: var(--teal-ink); }
.changes .rating { background: var(--mustard-soft); color: var(--mustard-ink); }
.changes .removed { background: var(--coral-soft); color: var(--coral-ink); text-decoration: line-through; }
.changes .change-fields { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 2px; font-size: 13px; }
.changes .change-fields li { display: block; }
.changes .change-fields span { padding: 0; border-radius: 0; color: var(--muted); }
.grid.small { grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); }
.grid.small img { width: 100%; aspect-ratio: 1; object-fit: cover; opacity: .6; }
.empty, .error { padding: 40px 0; color: var(--muted); }
.error { color: var(--danger); }

/* Detail view */
.viewer { display: grid; grid-template-columns: 1fr 400px; height: calc(100vh - 65px); }
.stage {
  position: relative; display: flex; align-items: center; justify-content: center;
  background: var(--stage); overflow: hidden;
}
.stage img { max-width: 100%; max-height: 100%; object-fit: contain; }
.back {
  position: absolute; top: 12px; left: 12px; padding: 6px 12px;
  color: #fff; background: rgba(0, 0, 0, .45); border-radius: 999px;
}
.actions { position: absolute; top: 12px; right: 12px; display: flex; gap: 8px; }
.actions form { margin: 0; }
.icon {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0; border: 0; cursor: pointer;
  color: #fff; background: rgba(0, 0, 0, .45); border-radius: 999px;
}
.icon:hover { background: rgba(0, 0, 0, .7); }
.icon svg {
  width: 22px; height: 22px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.icon.favourite.active svg { fill: var(--coral); stroke: var(--coral); }
.icon.trash.active { background: var(--danger-bg); }
span.icon { cursor: default; }
span.icon:hover { background: rgba(0, 0, 0, .45); }
.icon.tag:not(.active) { color: rgba(255, 255, 255, .45); }
.icon.tag.active { background: var(--accent); }
.stage img.trashed { opacity: .45; }
/* Videos: as large as the stage allows, never beyond their size. */
.stage .player {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; background: #000;
}
.stage .player.trashed { opacity: .45; }
.stage .step { z-index: 2; }
.icon.play .pause-icon, .icon.play.playing .play-icon { display: none; }
.icon.play.playing .pause-icon { display: block; }
.icon.mute .muted-icon, .icon.mute.muted .sound-icon { display: none; }
.icon.mute.muted .muted-icon { display: block; }
.icon.play svg path:first-child { fill: currentColor; }
.icon.play .pause-icon path { fill: none; stroke-width: 3; }
/* Zoom: fit (as large as the stage allows, at most at 100 %) or 100 %. */
.canvas {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.canvas .zoom-target { display: contents; }
.canvas .fit {
  width: 100%; height: 100%; object-fit: contain;
  max-width: var(--w); max-height: var(--h); cursor: zoom-in;
}
.canvas.at-full .fit { cursor: default; }
/* The full photo is loaded only once shown (loading="lazy"). */
.canvas .full { display: none; }
/* Flex with auto margins: centred while the photo is smaller than the
   stage, scrollable from its edge once it is larger. */
.viewer:has(#zoom:checked) .canvas {
  align-items: flex-start; justify-content: flex-start; overflow: auto;
}
.viewer:has(#zoom:checked) .canvas .fit { display: none; }
.viewer:has(#zoom:checked) .canvas .full {
  display: block; flex: none; width: var(--w); height: var(--h);
  max-width: none; max-height: none; margin: auto; cursor: zoom-out;
  /* The preview stands in until the full photo has loaded. */
  background: var(--preview) center / 100% 100% no-repeat;
}
.back, .actions, .step, .position { z-index: 2; }
.zoom-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.zoom-toggle:has(input:checked) { background: var(--accent); }
.zoom-toggle:has(input:focus-visible) { outline: 2px solid #fff; }
.zoom-toggle:has(input:disabled) { opacity: .4; cursor: default; }
.zoom-toggle .zoom-out, .zoom-toggle:has(input:checked) .zoom-in { display: none; }
.zoom-toggle:has(input:checked) .zoom-out { display: block; }
.info-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.info-toggle:has(input:checked) { background: var(--accent); }
.info-toggle:has(input:focus-visible) { outline: 2px solid #fff; }
.viewer:has(#hide-info:checked) { grid-template-columns: 1fr; }
.viewer:has(#hide-info:checked) .info { display: none; }
#shortcuts {
  padding: 16px 20px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--bg); color: var(--text);
}
#shortcuts::backdrop { background: rgba(0, 0, 0, .4); }
#shortcuts h2 { margin: 0 0 10px; font-size: 16px; }
#shortcuts th { padding: 4px 16px 4px 0; text-align: left; font-weight: 400; }
kbd {
  padding: 1px 6px; border: 1px solid var(--line); border-radius: 4px;
  background: var(--panel); font-family: inherit;
}

/* Marks on gallery tiles */
.tile { position: relative; }
.tile.trashed img { opacity: .4; }
.badges { position: absolute; top: 6px; right: 6px; display: flex; gap: 4px; }
.badge {
  display: flex; padding: 4px; border-radius: 999px;
  background: rgba(0, 0, 0, .45); color: #fff;
}
.badge svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.badge.favourite svg { fill: var(--coral); stroke: var(--coral); }
.badge.trash { background: var(--danger-bg); }
.badge.tag { background: var(--accent); }
.badge.unsaved { background: var(--mustard); color: #1F2A2A; }
.badge.undated { background: var(--slate); }
/* Albums and shares stay quiet: they are common and change nothing. */
.badge.album, .badge.shared { background: rgba(0, 0, 0, .55); }
/* Narrow tiles on phones: smaller marks, so up to six fit beside the circle. */
@media (max-width: 760px) {
  .badges { top: 5px; right: 5px; gap: 2px; }
  .badge { padding: 3px; }
  .badge svg { width: 12px; height: 12px; }
}
/* Bottom right: the stars of a rated photo and the length of a video; on a
   narrow tile the length moves above the stars. */
.tile-meta {
  position: absolute; right: 6px; bottom: 6px; z-index: 1;
  display: flex; flex-wrap: wrap-reverse; justify-content: flex-end; gap: 4px;
  max-width: calc(100% - 56px); pointer-events: none;
}
.tile-stars, .tile-duration {
  padding: 2px 7px; border-radius: 999px; background: rgba(0, 0, 0, .55);
  color: var(--mustard); font-size: 12px; line-height: 16px; letter-spacing: 1px;
}
.tile-duration { color: #fff; font-size: 11px; font-weight: 600; letter-spacing: .5px; }
.step {
  position: absolute; top: 50%; transform: translateY(-50%);
  padding: 10px 16px; font-size: 32px; line-height: 1;
  color: #fff; background: rgba(0, 0, 0, .35); border-radius: 999px;
}
.step:hover { background: rgba(0, 0, 0, .6); text-decoration: none; }
.step.previous { left: 12px; }
.step.next { right: 12px; }
.info { overflow-y: auto; padding: 20px 22px 40px; border-left: 1px solid var(--line); }
.info h1 { font-size: 18px; margin: 0 0 8px; word-break: break-all; }
.info h2 { font-size: 14px; margin: 26px 0 8px; }
.info h3 { font-size: 13px; font-weight: 600; color: var(--muted); margin: 12px 0 4px; }
.info h2 .source { margin-left: 6px; }
.source {
  font-size: 11px; font-weight: 400; color: var(--muted); border: 1px solid var(--line);
  border-radius: 999px; padding: 0 7px; vertical-align: 1px;
}
.source.own { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
/* Edited in place: while the form is open, what it changes is hidden. */
.edit-block:has(> details[open]) .shown,
.edit-block:has(details[open]) > .shown { display: none; }
.head-box .edit-box { margin: 0 0 4px; }
.head-box .hint.changed { margin: 4px 0 0; }
.own-box {
  margin: 26px 0 8px; padding: 2px 12px 10px; border: 1px dashed var(--line);
  border-radius: 12px; background: var(--panel);
}
.own-box .own-head { font-size: 13px; color: var(--muted); margin: 10px 0 0; }
.own-box h2 { margin-top: 14px; }
.description { color: var(--muted); }
.core { display: grid; grid-template-columns: 100px 1fr; gap: 8px 12px; margin: 16px 0; }
.core dt { color: var(--muted); }
.core dd { margin: 0; }
/* Geo-Tagging (photo.html): the button, and where a place found came from. */
.geotag-form { display: inline; margin: 0; }
.geotag-form button.icon { width: 24px; height: 24px; vertical-align: middle; }
.geotag-form button.icon svg { width: 14px; height: 14px; }
.button.geotag { padding: 4px 12px; font-size: 14px; }
.geotag-source {
  display: flex; margin: 0 0 6px; align-items: center; flex-wrap: wrap; gap: 4px;
  color: var(--muted); font-size: 13px;
}
.geotag-source .icon svg { width: 16px; height: 16px; }
.geotag-missed { margin: 6px 0 0; }
/* The info column's two tabs (photo.html): radio buttons, no JavaScript. */
.info-tabs { display: flex; gap: 4px; margin: 14px 0 4px; border-bottom: 1px solid var(--line); }
.info-tabs label {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 8px 10px; color: var(--muted); border-bottom: 2px solid transparent;
  margin-bottom: -1px; font-size: 14px;
}
.info-tabs kbd { font-size: 11px; }
#info-essential:checked ~ .info-tabs label[for=info-essential],
#info-all:checked ~ .info-tabs label[for=info-all] {
  color: var(--accent); border-bottom-color: var(--accent); font-weight: 600;
}
#info-essential:focus-visible ~ .info-tabs label[for=info-essential],
#info-all:focus-visible ~ .info-tabs label[for=info-all] { outline: 2px solid var(--accent); }
.info-pane.info-all, #info-all:checked ~ .info-essential { display: none; }
#info-all:checked ~ .info-pane.info-all { display: block; }
.info-all .hint:first-child { margin-top: 12px; }
/* Ort, Beschriftung, Aufgenommen: what applies, and a form that unfolds. */
.place-line, .taken-line, .gps { margin: 0 0 6px; }
.gps { color: var(--muted); font-size: 13px; }
.changed { box-shadow: inset 3px 0 0 var(--star); padding-left: 8px; }
.core.caption { margin: 0 0 8px; }
.core.caption dd { white-space: pre-line; overflow-wrap: anywhere; }
.core.caption .hint { display: block; margin: 2px 0 0; white-space: normal; }
.edit-box { border-top: 0; padding: 0; margin: 6px 0 0; }
.edit-box summary {
  display: inline-flex; align-items: center; gap: 6px; font-weight: 400;
  font-size: 14px; color: var(--accent); list-style: none;
}
.edit-box summary::-webkit-details-marker { display: none; }
.edit-box summary svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.edit-form { display: grid; gap: 4px; margin: 8px 0 4px; }
.edit-form label { font-size: 13px; color: var(--muted); margin-top: 6px; }
.edit-form input[type=text], .edit-form input[type=datetime-local], .edit-form textarea {
  font: inherit; color: var(--text); background: var(--panel);
  border: 1px solid var(--line); border-radius: 8px; padding: 7px 10px; width: 100%;
}
.edit-form textarea { resize: vertical; }
.edit-form input:focus, .edit-form textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.edit-buttons { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 6px; }
.edit-buttons .button { padding: 5px 12px; font-size: 14px; }
.undo-form { margin: 0 0 6px; }
.map {
  height: 220px; margin: 4px 0 8px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--panel);
}
.path { word-break: break-all; color: var(--muted); font-size: 13px; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; padding: 0; margin: 0; }
.chips a {
  display: block; padding: 4px 12px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent);
}
.hint { color: var(--muted); font-size: 13px; margin: 0 0 8px; }
/* Keyword editor in the detail view (keywords.js adds the suggestions). */
.chips.editable li {
  display: flex; align-items: center; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent);
}
.chips.editable a { padding: 4px 4px 4px 12px; background: none; color: inherit; }
.chips.editable form, .hidden-keywords form { display: contents; }
.chips.editable button.remove {
  border: 0; background: none; color: inherit; cursor: pointer; opacity: .6;
  font: inherit; font-size: 16px; line-height: 1; padding: 4px 10px 4px 4px;
}
.chips.editable button.remove:hover,
.chips.editable button.remove:focus-visible { opacity: 1; }
/* Added in cheapshots, not in the file: outlined. */
.chips.editable li.added { background: none; box-shadow: inset 0 0 0 1.5px var(--accent); }
/* The first ⌫ in the empty field marks the keyword the second one removes. */
.chips.editable li.armed { background: var(--danger-bg); color: var(--on-danger); box-shadow: none; }
.keyword-add { position: relative; display: flex; gap: 6px; margin: 10px 0 6px; }
.keyword-add input[type=text] {
  flex: 1; min-width: 0; padding: 7px 12px; border-radius: 999px; font: inherit;
  border: 1px solid var(--line); background: var(--bg); color: var(--text);
}
.keyword-add input[type=text]:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.icon.add { flex: none; width: 36px; height: 36px; background: var(--accent); color: var(--bg); }
.icon.add:hover { background: var(--accent); opacity: .85; }
.suggestions {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 10;
  list-style: none; margin: 0; padding: 4px; border-radius: 12px;
  background: var(--bg); border: 1px solid var(--line);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .15);
}
.suggestions li {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 6px 10px; border-radius: 8px; cursor: pointer;
}
.suggestions li[aria-selected="true"] { background: var(--accent-soft); color: var(--accent); }
.suggestions .count { color: var(--muted); font-size: 12px; white-space: nowrap; }
.suggestions .group { color: var(--muted); font-size: 12px; padding: 6px 10px 2px; cursor: default; }
.suggestions mark { background: none; color: inherit; font-weight: 700; }
.suggestions .new { border-top: 1px solid var(--line); margin-top: 4px; border-radius: 0 0 8px 8px; }
.hidden-keywords { font-size: 13px; color: var(--muted); margin: 4px 0; }
.hidden-keywords s { color: var(--text); }
.hidden-keywords > span { white-space: nowrap; }
.hidden-keywords > span:not(:last-child) button::after { content: ","; color: var(--muted); }
.hidden-keywords button.add {
  display: inline-flex; align-items: center; padding: 0; border: 0;
  background: none; color: var(--accent); cursor: pointer; font: inherit;
}
.hidden-keywords svg {
  width: 13px; height: 13px; margin-right: 3px; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Star rating in the detail view: hovering a star previews that rating. */
.stars { display: flex; align-items: center; gap: 2px; margin: 0 0 8px; }
.stars form { display: contents; }
.stars button {
  display: flex; padding: 2px; border: 0; background: none; cursor: pointer; color: var(--star);
}
.stars svg {
  width: 26px; height: 26px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linejoin: round;
}
.stars .star.on svg, .stars:has(.star:hover) .star svg { fill: currentColor; }
.stars form:has(.star:hover) ~ form .star svg { fill: none; }
.stars .unrate { color: var(--muted); margin-left: 6px; }
.stars .unrate svg { width: 18px; height: 18px; stroke-width: 2; }
.stars .unrate:hover, .stars .unrate:focus-visible { color: var(--text); }
.keyword-editor .saved { font-size: 13px; color: var(--keep); margin: 0 0 8px; }
.keyword-editor .saved:empty { display: none; }
details { border-top: 1px solid var(--line); padding: 6px 0; }
summary { cursor: pointer; font-weight: 600; padding: 4px 0; }
.fields { width: 100%; border-collapse: collapse; font-size: 13px; }
.fields th {
  width: 45%; padding: 3px 8px 3px 0; text-align: left; vertical-align: top;
  font-weight: 400; color: var(--muted); word-break: break-word;
}
.fields td { padding: 3px 0; word-break: break-word; }
.fields pre { margin: 0; white-space: pre-wrap; font-size: 12px; }
.footer { padding: 16px 24px; color: var(--muted); font-size: 12px; }

/* Phones */
@media (max-width: 760px) {
  /* Tight, so the search field gets as much of the width as it can. */
  .topbar { gap: 8px; padding: 8px 8px 8px 4px; }
  .icon.open-sidebar { margin: 0 -4px 0 0; }
  .layout { grid-template-columns: 1fr; }
  .facets {
    display: none; position: fixed; top: 0; bottom: 0; left: 0; z-index: 30;
    width: min(80vw, 300px); height: 100vh; height: 100dvh; padding: 16px; background: var(--bg);
  }
  body:has(#sidebar:checked) .facets { display: flex; }
  body:has(#sidebar:checked) .backdrop {
    display: block; position: fixed; inset: 0; z-index: 20; background: rgba(0, 0, 0, .45);
  }
  .content { padding: 12px; }
  .mapview { grid-template-columns: 1fr; }
  /* Leaflet makes the map position: relative, so the offset must go too. */
  .photo-map { position: static; top: auto; height: 45vh; }
  .map-photos .grid { grid-template-columns: repeat(3, 1fr); }
  .grid { grid-template-columns: repeat(3, 1fr); gap: 2px; }
  .content { --row-height: 120px; }
  .viewer { grid-template-columns: 1fr; height: auto; }
  .info { border-left: 0; }
}

/* Multi-selection in the gallery (selection.js). The circle is faint at
   rest, clear on hover and while selecting; touch screens have no hover. */
.tile .pick {
  position: absolute; top: 6px; left: 6px; z-index: 2;
  width: 24px; height: 24px; border-radius: 50%; box-sizing: border-box;
  border: 2px solid #fff; background: rgba(0, 0, 0, .25);
  display: flex; align-items: center; justify-content: center;
  opacity: .55; transition: opacity .12s;
}
.tile .pick svg {
  width: 14px; height: 14px; fill: none; stroke: #fff; stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round; opacity: 0;
}
.tile:hover .pick, .tile:focus-visible .pick, .selecting .tile .pick { opacity: 1; }
@media (hover: none) {
  .tile .pick { opacity: .9; }
  /* No link preview on a long press, which selects instead. */
  .tile { -webkit-touch-callout: none; }
}
.tile.selected .pick { background: var(--accent); border-color: var(--accent); }
.tile.selected .pick svg { opacity: 1; }
.tile.selected { background: var(--accent-soft); }
.tile.selected img { transform: scale(.88); border-radius: 8px; }
.selecting .tile:hover img { transform: none; }
.selecting .tile.selected:hover img { transform: scale(.88); }
/* The photo the arrow keys are on (selection.js). */
.tile.cursor { outline: 4px solid var(--accent); outline-offset: 2px; z-index: 3; }
.tile.cursor::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  box-shadow: inset 0 0 0 2px #fff;
}
.tile:focus:not(.cursor) { outline: none; }

/* The selection bar covers the top bar while photos are selected. */
.selection-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 20; box-sizing: border-box;
  display: flex; align-items: center; gap: 8px; padding: 0 24px;
  background: var(--bg); border-bottom: 1px solid var(--line);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .08);
}
.selection-bar[hidden], .selection-bar .icon[hidden] { display: none; }
.selection-bar .count { font-weight: 600; font-size: 17px; white-space: nowrap; }
.selection-bar .clear {
  display: inline-flex; align-items: center; gap: 6px; margin-right: auto;
  height: 40px; padding: 0 14px 0 10px; border: 1px solid var(--line); border-radius: 999px;
  background: none; color: inherit; font: inherit; font-size: 14px; cursor: pointer; white-space: nowrap;
}
.selection-bar .clear:hover { background: var(--accent-soft); }
.selection-bar .clear svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
}
.selection-bar .sel-actions { display: flex; align-items: center; gap: 8px; }
/* Words under the icons and "Mehr" only in the phone's bottom bar. */
.selection-bar .label, .selection-bar .more-toggle { display: none; }
.selection-bar .icon { color: var(--text); background: var(--panel); }
.selection-bar .icon:hover { background: var(--accent-soft); }
.selection-bar [data-act="favourite"].active svg { fill: var(--fav); stroke: var(--fav); }
.selection-bar [data-act="trash"].active { background: var(--danger-bg); color: var(--on-danger); }
.tile.selected .tile-meta { right: calc(6% + 6px); bottom: calc(6% + 6px); }
/* File type bottom left, in the style of the stars. */
.tile-type {
  position: absolute; left: 6px; bottom: 6px; z-index: 1;
  padding: 1px 6px; border-radius: 999px; background: rgba(0, 0, 0, .55);
  color: #fff; font-size: 10px; font-weight: 600; line-height: 16px; letter-spacing: .5px;
  pointer-events: none;
}
.tile.selected .tile-type { left: calc(6% + 6px); bottom: calc(6% + 6px); }
/* Stars for all selected photos: a small popover below the star icon. */
.star-pop {
  position: fixed; z-index: 25; width: 260px; box-sizing: border-box; padding: 12px 14px;
  background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
}
.star-pop[hidden] { display: none; }
.star-pop .mix { margin: 0 0 8px; font-size: 13px; color: var(--muted); }
.star-pop .stars-row { display: flex; align-items: center; gap: 2px; }
.star-pop [data-stars] {
  display: flex; padding: 2px; border: 0; background: none; cursor: pointer; color: var(--star);
}
.star-pop svg {
  width: 28px; height: 28px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linejoin: round;
}
.star-pop .on svg, .star-pop .preview svg { fill: currentColor; }
.star-pop .stars-row:hover .on:not(.preview) svg { fill: none; }
.star-pop .none {
  margin-left: auto; padding: 4px 10px; border: 1px solid var(--line);
  border-radius: 999px; color: var(--text); font: inherit; font-size: 13px;
}
.star-pop .none:hover { background: var(--accent-soft); }
/* The question before a download of photos with changes not in their
   files: below the button in the gallery, a centred popover in the detail view. */
.download-control { display: contents; }
.download-pop {
  position: fixed; z-index: 25; width: 340px; max-width: calc(100vw - 16px);
  box-sizing: border-box; padding: 14px 16px;
  background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
}
.download-pop[hidden] { display: none; }
.download-pop::backdrop { background: rgba(0, 0, 0, .25); }
.download-pop h2 { margin: 0 0 6px; font-size: 15px; }
.download-pop .question { margin: 0 0 8px; font-size: 14px; line-height: 1.4; }
.download-pop .hint:empty { display: none; }
.download-pop .choices { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; margin-top: 12px; }
.download-pop .button { padding: 6px 12px; font-size: 14px; }
.download-pop .button kbd { background: none; border-color: currentColor; color: inherit; font-size: 11px; opacity: .8; }
.toast {
  position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 30;
  margin: 0; padding: 10px 16px; border-radius: 10px; background: var(--text); color: var(--bg);
  font-size: 14px; box-shadow: 0 6px 20px rgba(0, 0, 0, .25);
}
.toast:empty { display: none; }

/* Keywords of several photos: solid on all of them, dashed on some. */
dialog.bulk-keywords, dialog.bulk-caption, dialog.bulk-geotag {
  width: min(560px, calc(100vw - 32px)); padding: 0; border: 1px solid var(--line);
  border-radius: 14px; background: var(--bg); color: var(--text);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .3);
}
dialog.bulk-keywords::backdrop, dialog.bulk-caption::backdrop, dialog.bulk-geotag::backdrop { background: rgba(10, 12, 20, .45); }
dialog.bulk-keywords header, dialog.bulk-caption header, dialog.bulk-geotag header { display: flex; align-items: center; gap: 12px; padding: 16px 20px 0; }
dialog.bulk-keywords h2, dialog.bulk-caption h2, dialog.bulk-geotag h2 { font-size: 17px; margin: 0; }
dialog.bulk-keywords .strip { display: flex; gap: 4px; margin-left: auto; }
dialog.bulk-keywords .strip img { width: 34px; height: 34px; object-fit: cover; border-radius: 6px; }
dialog.bulk-keywords .strip span { font-size: 12px; color: var(--muted); align-self: center; margin-left: 4px; }
dialog.bulk-keywords .body, dialog.bulk-caption .body, dialog.bulk-geotag .body { padding: 8px 20px 16px; }
dialog.bulk-keywords h3 { font-size: 13px; color: var(--muted); font-weight: 600; margin: 14px 0 6px; }
.legend { font-size: 12px; color: var(--muted); margin: -2px 0 8px; }
.chips.bulk li {
  display: flex; align-items: center; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent); font-size: 14px;
}
.chips.bulk .name { padding: 4px 2px 4px 12px; }
.chips.bulk .share { font-size: 11px; opacity: .75; margin-left: 6px; }
.chips.bulk button {
  border: 0; background: none; color: inherit; cursor: pointer; font: inherit;
  padding: 4px 8px 4px 4px; opacity: .65; font-size: 15px; line-height: 1;
}
.chips.bulk button:hover, .chips.bulk button:focus-visible { opacity: 1; }
.chips.bulk li.partial { background: none; outline: 1.5px dashed var(--accent); outline-offset: -1.5px; }
.chips.bulk li.added { background: var(--teal-soft); color: var(--teal-ink); }
.chips.bulk li.removed {
  background: none; color: var(--muted); text-decoration: line-through;
  outline: 1.5px dashed var(--line); outline-offset: -1.5px;
}
.chips.bulk li.none { background: none; color: var(--muted); }
.bulk-add { position: relative; display: flex; gap: 6px; margin-top: 12px; }
.bulk-add input {
  flex: 1; min-width: 0; padding: 8px 12px; border-radius: 999px; font: inherit;
  border: 1px solid var(--line); background: var(--bg); color: var(--text);
}
.bulk-add input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.bulk-add .suggestions { right: 42px; }
dialog.bulk-caption form { margin: 0; }
dialog.bulk-caption .body { max-height: 70vh; overflow-y: auto; }
dialog.bulk-caption label.check { display: flex; gap: 8px; align-items: center; color: var(--text); margin-top: 10px; }
/* Geo-Tagging for a selection: the places it would set, to judge first. */
dialog.bulk-geotag .body { max-height: 70vh; overflow-y: auto; }
dialog.bulk-geotag footer .undo { margin-right: auto; }
dialog.bulk-geotag footer .undo[hidden] { display: none; }
.geotag-wait { color: var(--muted); }
.geotag-places { list-style: none; margin: 8px 0 0; padding: 0; }
.geotag-places li {
  display: grid; grid-template-columns: 145px 1fr; column-gap: 12px; align-items: center;
  padding: 8px 0; border-bottom: 1px solid var(--line);
}
.geotag-places .strip { grid-row: span 2; display: flex; gap: 3px; }
.geotag-places .strip img { width: 34px; height: 34px; object-fit: cover; border-radius: 6px; }
.geotag-places .name { font-weight: 600; overflow-wrap: anywhere; }
.geotag-places .how { font-size: 13px; color: var(--muted); }
@media (max-width: 760px) {
  .geotag-places li { grid-template-columns: 70px 1fr; }
  .geotag-places .strip img:nth-child(n+3) { display: none; }
}
.bulk-summary { font-size: 13px; color: var(--muted); margin: 14px 0 0; min-height: 1.4em; }
dialog.bulk-keywords footer, dialog.bulk-caption footer, dialog.bulk-geotag footer {
  display: flex; justify-content: flex-end; gap: 10px; padding: 12px 20px 16px;
  border-top: 1px solid var(--line); background: var(--panel); border-radius: 0 0 14px 14px;
}
.button.primary { background: var(--accent); color: var(--bg); border-color: var(--accent); }
.button.primary:disabled { opacity: .45; cursor: default; }
@media (max-width: 760px) {
  /* Phones: × and the count on top; the actions in a bar at the bottom,
     where the thumb is, with words under the icons. "Mehr" opens the
     others as a sheet above that bar. */
  .selection-bar { gap: 10px; padding: 0 12px; }
  .selection-bar .count { order: 1; margin-right: auto; font-size: 18px; }
  .selection-bar .clear {
    width: 48px; height: 48px; padding: 0; margin-right: 0; justify-content: center;
    border: 0; background: var(--panel);
  }
  .selection-bar .clear svg { width: 22px; height: 22px; }
  .selection-bar .clear .long { display: none; }
  .selection-bar .sel-actions {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; box-sizing: border-box;
    flex-wrap: wrap; gap: 2px; padding: 6px 6px calc(8px + env(safe-area-inset-bottom));
    background: var(--panel); border-top: 1px solid var(--line); box-shadow: 0 -2px 10px rgba(0, 0, 0, .08);
  }
  .selection-bar .sel-actions .icon { display: none; }
  .selection-bar .sel-actions .main:not([hidden]) {
    display: flex; flex: 1 1 0; min-width: 0; width: auto; height: auto; min-height: 58px;
    flex-direction: column; gap: 3px; border-radius: 14px; background: none;
  }
  .selection-bar .sel-actions .main .label {
    display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: 12px; line-height: 1.2;
  }
  /* The bottom row in this order; the sheet's rows (order 0) come first. */
  .selection-bar [data-act="favourite"] { order: 1; }
  .selection-bar [data-act="album"] { order: 2; }
  .selection-bar [data-act="download"] { order: 3; }
  .selection-bar [data-act="trash"] { order: 4; }
  .selection-bar .more-toggle { order: 5; }
  .selection-bar.more-open .sel-actions {
    padding-top: 10px; border-radius: 18px 18px 0 0; box-shadow: 0 -4px 20px rgba(0, 0, 0, .18);
  }
  .selection-bar.more-open .sel-actions .in-more:not([hidden]) {
    display: flex; flex: 0 0 100%; width: auto; height: auto; min-height: 52px;
    justify-content: flex-start; gap: 16px; padding: 0 16px; border-radius: 12px; background: none;
  }
  .selection-bar.more-open .sel-actions .in-more .label { display: block; font-size: 16px; }
  .selection-bar.more-open .more-toggle { background: var(--accent-soft); }
  /* The gallery behind the open sheet is dimmed; a tap there closes it. */
  .selection-bar.more-open::after {
    content: ""; position: fixed; inset: 0; z-index: 19; background: rgba(20, 27, 27, .4);
  }
  body.selecting .content { padding-bottom: 96px; }
  body.selecting .toast { bottom: calc(96px + env(safe-area-inset-bottom)); }
  /* A sheet from the bottom on phones. */
  dialog.bulk-keywords, dialog.bulk-caption, dialog.bulk-geotag { width: 100vw; max-width: 100vw; margin: auto 0 0; border-radius: 16px 16px 0 0; }
  dialog.bulk-keywords .strip img { width: 28px; height: 28px; }
  dialog.bulk-keywords footer { border-radius: 0; }
}
/* --- albums ----------------------------------------------------------- */
.collections .album svg { stroke: var(--accent); }
.icon.album:not(.active) { color: rgba(255, 255, 255, .45); }
.icon.album.active { background: var(--accent); }
.albums-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 12px 0 16px; }
.albums-head h1 { margin: 0; font-size: 22px; }
.albums-head .spacer { flex: 1; }
.albums-head .icon { color: var(--text); background: var(--panel); }
.album-cards { display: grid; gap: 18px 14px; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
@media (max-width: 760px) { .album-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 10px; } }
.album-card { display: flex; flex-direction: column; gap: 5px; color: var(--text); min-width: 0; }
.album-card:hover { text-decoration: none; }
.album-card .cover {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1; border-radius: 12px; overflow: hidden; background: var(--panel); color: var(--muted);
}
.album-card .cover img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .15s; }
.album-card:hover .cover img { transform: scale(1.04); }
.album-card .cover svg { width: 40px; height: 40px; fill: none; stroke: currentColor; stroke-width: 1.5; }
.album-card .name { font-weight: 600; overflow-wrap: anywhere; }
.album-card .meta { color: var(--muted); font-size: 13px; margin-top: -3px; }
.album-head { display: grid; gap: 4px; margin: 4px 0 14px; }
.album-head .to-albums { font-size: 14px; justify-self: start; }
.album-head .title-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.album-head h1 { margin: 0; font-size: 24px; overflow-wrap: anywhere; }
.album-head .meta { color: var(--muted); }
.album-head .desc { margin: 2px 0 0; max-width: 65ch; line-height: 1.45; white-space: pre-line; }
.album-head .icon { width: 34px; height: 34px; color: var(--text); background: var(--panel); }
.album-head .icon:hover { background: var(--accent-soft); }
.album-head .icon svg { width: 17px; height: 17px; }
.album-head .icon.danger:hover { background: var(--danger-bg); color: var(--on-danger); }
.album-form {
  width: min(440px, calc(100vw - 32px)); box-sizing: border-box; padding: 18px 20px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--bg); color: var(--text);
}
.album-form::backdrop { background: rgba(0, 0, 0, .4); }
.album-form h2 { margin: 0 0 12px; font-size: 17px; }
.album-form label { display: grid; gap: 4px; margin-bottom: 10px; font-size: 13px; color: var(--muted); }
.album-form input, .album-form textarea {
  font: inherit; font-size: 15px; color: var(--text); background: var(--bg);
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
}
.album-form .buttons { display: flex; justify-content: flex-end; gap: 8px; margin-top: 6px; }
/* "Zu Album hinzufügen" for a selection: a list with a search field. */
.album-pop {
  position: fixed; z-index: 25; width: 300px; box-sizing: border-box; padding: 10px;
  background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
}
.album-pop[hidden] { display: none; }
.album-pop h2 { font-size: 14px; margin: 2px 4px 8px; }
.album-pop input {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 14px; padding: 7px 10px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--text);
}
.album-pop ul { list-style: none; margin: 8px 0 0; padding: 0; max-height: 260px; overflow-y: auto; }
.album-pop li.empty { padding: 6px; color: var(--muted); font-size: 13px; }
.album-pop li button {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 6px; border: 0; border-radius: 8px;
  background: none; color: inherit; font: inherit; font-size: 14px; text-align: left; cursor: pointer;
}
.album-pop li button .cover { width: 34px; height: 34px; border-radius: 6px; object-fit: cover; flex: none; background: var(--panel); }
.album-pop li button .n { margin-left: auto; color: var(--muted); font-size: 12px; white-space: nowrap; }
.album-pop li button.active, .album-pop li button:hover { background: var(--accent-soft); }
.album-pop li.create button { color: var(--accent); font-weight: 600; }
.album-pop li.create .plus {
  width: 34px; height: 34px; border-radius: 6px; border: 2px dashed var(--accent); flex: none;
  display: flex; align-items: center; justify-content: center; font-size: 18px; box-sizing: border-box;
}
.album-pop .hint { margin: 8px 4px 0; color: var(--muted); font-size: 12px; }
.album-editor .cover-form { margin: 10px 0 8px; }
.album-editor .set-cover { font-size: 14px; padding: 6px 12px; }
.album-editor .set-cover.active { box-shadow: inset 0 0 0 1.5px var(--accent); }
.albums .to-photos { display: inline-block; margin-top: 4px; font-size: 14px; }
.albums .hint { margin-top: 20px; color: var(--muted); }
/* --- Entdecken: the tag cloud above the gallery --------------------------- */
.collections .compass svg { stroke: var(--accent); }
.discover { margin: 4px 0 18px; padding: 12px 16px 14px; border-radius: 12px; background: var(--panel); }
.discover-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.discover-head h1 { margin: 0; font-size: 20px; }
.discover-head .spacer { flex: 1; }
.discover .tag-filter { position: relative; display: flex; align-items: center; margin: 0; }
.discover .tag-filter-label { position: absolute; left: 9px; display: flex; color: var(--muted); cursor: text; }
.discover .tag-filter-label svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.discover .tag-filter input {
  width: 190px; max-width: 100%; box-sizing: border-box; font: inherit; font-size: 14px; padding: 6px 10px 6px 30px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--bg); color: var(--text);
}
.discover .tag-filter input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.sort-switch { display: inline-flex; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; font-size: 13px; }
.sort-switch a, .sort-switch span { padding: 5px 11px; background: var(--bg); color: var(--muted); }
.sort-switch a:hover { text-decoration: none; color: var(--text); }
.sort-switch .on { background: var(--accent); color: var(--bg); }
.discover .icon.close-bar { width: 30px; height: 30px; flex: none; background: none; color: var(--muted); }
.discover .icon.close-bar:hover { background: var(--accent-soft); color: var(--text); }
.discover .icon.close-bar svg { width: 16px; height: 16px; }
.chosen-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0 0 10px; font-size: 14px; }
.chosen-row .label { color: var(--muted); }
.chosen-row a.chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 8px 3px 11px; border-radius: 999px;
  background: var(--accent); color: var(--bg); font-weight: 600;
}
.chosen-row a.chip:hover { text-decoration: none; filter: brightness(1.1); }
.chosen-row a.chip span { opacity: .8; }
.chosen-row .discover-clear { font-size: 13px; margin-left: 4px; }
.cloud { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; line-height: 1.25; }
.cloud a { color: var(--text); white-space: nowrap; }
.cloud a[hidden] { display: none; }
.cloud a:hover { color: var(--accent); text-decoration: none; }
.cloud a .n { font-size: 11px; color: var(--muted); margin-left: 2px; vertical-align: super; }
.cloud a.hit { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.cloud .empty { margin: 0; color: var(--muted); }
.cloud-all { position: absolute; opacity: 0; pointer-events: none; }
.cloud.capped { max-height: 9.5em; overflow: hidden; mask-image: linear-gradient(#000 70%, transparent); }
.cloud-all:checked + .cloud.capped, .cloud.capped.typing { max-height: none; mask-image: none; }
.cloud-foot { display: flex; gap: 12px; margin-top: 10px; font-size: 13px; color: var(--muted); }
.cloud-foot .cloud-more { color: var(--accent); cursor: pointer; }
.cloud-foot .cloud-more .hide, .discover:has(.cloud-all:checked) .cloud-foot .cloud-more .show { display: none; }
.discover:has(.cloud-all:checked) .cloud-foot .cloud-more .hide { display: inline; }

/* Duplicates (duplicates.html, duplicate_review.html) */
/* --keep, --keep-soft, --drop, --diff: see the tokens at the top. */
.collections .twins svg { stroke: var(--accent); }
.duplicates .to-photos { display: inline-block; margin-top: 4px; font-size: 14px; }
.kinds { display: flex; gap: 6px; flex-wrap: wrap; margin: 10px 0 14px; }
.kinds a {
  display: inline-flex; gap: 6px; align-items: baseline; padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--text); font-size: 14px;
}
.kinds a:hover { text-decoration: none; border-color: var(--muted); }
.kinds a.on { background: var(--accent); border-color: var(--accent); color: var(--bg); font-weight: 600; }
.kinds a.on .count { color: inherit; opacity: .8; }
.kind-help { margin: -4px 0 14px; color: var(--muted); font-size: 14px; max-width: 760px; }
.groups { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.group-card {
  display: flex; flex-direction: column; gap: 3px; padding: 10px; border-radius: 12px;
  background: var(--panel); color: var(--text); border: 1px solid transparent;
}
.group-card:hover { text-decoration: none; border-color: var(--line); }
.group-card .strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; margin-bottom: 5px; }
.group-card .strip > span { position: relative; aspect-ratio: 1; border-radius: 6px; overflow: hidden; background: var(--bg); }
.group-card .strip img { width: 100%; height: 100%; object-fit: cover; display: block; }
.group-card .strip .drop img { opacity: .4; }
.group-card .strip .drop::after {
  content: ""; position: absolute; right: 4px; top: 4px; width: 10px; height: 10px;
  border-radius: 50%; background: var(--drop);
}
.group-card .strip .rest { display: flex; align-items: center; justify-content: center; color: var(--muted); }
.group-card .name { font-weight: 600; }
.group-card .meta { font-size: 13px; color: var(--muted); }
.group-card .suggest { font-size: 13px; }
.tagline {
  display: inline-block; padding: 0 7px; margin-right: 4px; border-radius: 999px; font-size: 12px;
  background: var(--accent-soft); color: var(--accent); font-weight: 600;
}
.review-nav { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.review-nav .spacer { flex: 1; }
.review-nav .where { color: var(--muted); font-size: 14px; }
.review-nav .where i { font-style: normal; }
.review-nav .icon { color: var(--text); background: var(--panel); }
.review-nav .icon:hover { background: var(--accent-soft); }
.review-nav .icon.off { opacity: .35; }
.review h1 { margin: 6px 0 2px; font-size: 20px; }
.review-meta { margin: 0 0 12px; color: var(--muted); font-size: 14px; }
.compare {
  display: grid; gap: 12px; padding-bottom: 90px;
  /* auto-fit: two or three photos share the whole width, so they are large
     enough to compare. */
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
}
.cand { border-radius: 12px; border: 3px solid var(--keep); background: var(--bg); overflow: hidden; }
.cand:has(.drop-box:checked) { border-color: var(--drop); }
.cand .pic {
  position: relative; display: block; aspect-ratio: 4 / 3; max-height: 75vh; width: 100%;
  background: var(--stage); cursor: pointer;
}
.cand .pic img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* The grid (R) to check whether the horizon is level: lines every eighth
   of the box, light with a dark edge so they show on any photo. */
.grid-toggle { position: relative; }
.grid-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.grid-toggle:has(input:focus-visible) { outline: 2px solid var(--accent); }
.review-nav .grid-toggle:has(input:checked) { background: var(--accent); color: var(--bg); }
.review:has(#grid:checked) .cand .pic::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    repeating-linear-gradient(to bottom, transparent 0 calc(12.5% - 1px), rgba(255, 255, 255, .7) calc(12.5% - 1px) 12.5%),
    repeating-linear-gradient(to right, transparent 0 calc(12.5% - 1px), rgba(255, 255, 255, .7) calc(12.5% - 1px) 12.5%);
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, .8));
}
.cand .num, .cand .verdict, .cand .best { z-index: 1; }
/* No veil here, unlike the gallery: the photos are compared, so the red
   frame and badge mark those for the trash. */
.cand .pic:has(.drop-box:focus-visible) { outline: 3px solid var(--accent); outline-offset: -3px; }
.drop-box { position: absolute; opacity: 0; pointer-events: none; }
.cand .num {
  position: absolute; left: 8px; top: 8px; min-width: 26px; height: 26px; padding: 0 6px;
  display: flex; align-items: center; justify-content: center; border-radius: 999px;
  font-weight: 700; font-size: 14px; color: #fff; background: rgba(0, 0, 0, .55);
}
.cand .verdict {
  position: absolute; right: 8px; top: 8px; display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px 5px 8px; border-radius: 999px; font-size: 13px; font-weight: 600;
  color: var(--on-keep); background: var(--keep);
}
.cand .verdict.drop { background: var(--drop); }
.cand .verdict svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
}
.cand .pic:has(.drop-box:checked) .verdict.keep,
.cand .pic:not(:has(.drop-box:checked)) .verdict.drop { display: none; }
.cand .best {
  position: absolute; left: 8px; bottom: 8px; padding: 3px 9px; border-radius: 999px;
  font-size: 12px; color: #fff; background: rgba(0, 0, 0, .6);
}
.facts { width: 100%; border-collapse: collapse; font-size: 13px; }
.facts th, .facts td { padding: 4px 10px; text-align: left; vertical-align: top; overflow-wrap: anywhere; }
.facts th { width: 1%; white-space: nowrap; font-weight: 400; color: var(--muted); }
.facts tr.diff td { background: var(--diff); }
.facts td.top { font-weight: 700; }
/* The tally counts the marks with CSS counters, without JavaScript. */
.dup-form { counter-reset: keep drop; }
.drop-box:checked { counter-increment: drop; }
.drop-box:not(:checked) { counter-increment: keep; }
.tally::before { content: counter(keep) " behalten · " counter(drop) " in den Papierkorb"; }
.actionbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 15;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 24px; background: var(--bg); border-top: 1px solid var(--line);
}
.actionbar .tally { font-size: 14px; }
.actionbar label, .confirm .dup-merge { display: inline-flex; gap: 6px; align-items: center; font-size: 14px; cursor: pointer; }
.actionbar .spacer { flex: 1; }
.actionbar .warn { color: var(--drop); font-size: 13px; }
.dup-form:has(.drop-box:not(:checked)) .warn { display: none; }
.dup-form:not(:has(.drop-box:not(:checked))) .dup-apply { opacity: .45; pointer-events: none; }
.dup-form:has(.drop-box:checked) .dup-apply .if-none,
.dup-form:not(:has(.drop-box:checked)) .dup-apply .if-drop { display: none; }
@media (max-width: 760px) {
  .groups { grid-template-columns: 1fr; }
  .compare { grid-template-columns: repeat(2, 1fr); gap: 8px; padding-bottom: 150px; }
  .facts { font-size: 12px; }
  .facts th, .facts td { display: block; width: auto; padding: 3px 6px; }
  .facts th { padding-bottom: 0; }
  .cand .verdict span, .review-nav .where i { display: none; }
  .actionbar { padding: 10px 12px; }
  .actionbar .spacer { display: none; }
  .actionbar .button { flex: 1; justify-content: center; padding: 8px 10px; }
}

/* Content search (content.py): the switch in the search field (K), the
   chip above the results, and the suggested tags. */
.search { position: relative; }
.search:has(.ai-toggle) input[type=search] { padding-left: 48px; }
.ai-toggle {
  position: absolute; left: 6px; top: 50%; transform: translateY(-50%);
  width: 32px; height: 32px; border-radius: 999px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; color: var(--muted);
}
.ai-toggle:hover { background: var(--accent-soft); color: var(--text); }
.ai-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.ai-toggle:has(input:checked) { background: var(--accent); color: var(--bg); }
.ai-toggle:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
svg.filled { fill: currentColor; stroke: none; }
.ai-toggle svg { width: 18px; height: 18px; }
.content-chip {
  display: inline-flex; align-items: center; gap: 6px; margin-right: 8px; padding: 2px 10px;
  border-radius: 999px; background: var(--accent); color: var(--bg); font-weight: 600;
}
.content-chip:hover { text-decoration: none; }
.content-chip svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; }
.content-chip svg.filled { fill: currentColor; stroke: none; }
.view-actions .sort-switch { align-self: center; }
.suggest-head { display: flex; align-items: center; gap: 6px; margin: 12px 0 6px; font-size: 13px; color: var(--muted); }
.suggest-head svg, .bulk-suggested h3 svg { width: 14px; height: 14px; fill: var(--accent); vertical-align: -2px; }
.suggest-head form { margin-left: auto; }
.suggest-head button, .bulk-suggested .take-all {
  border: 0; background: none; padding: 0; font: inherit; font-size: 13px; color: var(--accent); cursor: pointer;
}
.bulk-suggested .take-all { margin-left: 8px; font-weight: 400; }
.chips.suggested li { display: flex; border-radius: 999px; box-shadow: inset 0 0 0 1.5px var(--line); }
.chips.suggested form { display: contents; }
.chips.suggested button {
  border: 0; background: none; color: var(--text); cursor: pointer; font: inherit;
  padding: 4px 12px 4px 10px;
}
.chips.suggested button:hover, .chips.suggested button:focus-visible { color: var(--accent); }
.sort-switch { white-space: nowrap; }
@media (max-width: 760px) {
  .summary-bar:has(.content-chip) { flex-wrap: wrap; gap: 8px; }
}

/* People (people.py): the page "Personen", "Wer ist das?", the head of a
   person above the gallery, and the faces in the detail view. */
.collections .people svg { stroke: var(--accent); }
.people .to-photos { display: inline-block; margin-top: 4px; font-size: 14px; }
.albums-head .icon.on { background: var(--accent); color: var(--bg); }
.people-title { font-size: 16px; margin: 22px 0 10px; display: flex; gap: 8px; align-items: baseline; }
.people-title .count { font-weight: 400; }
.people-grid { display: grid; gap: 14px 10px; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); }
.people-grid form { display: contents; }
.person-card {
  display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 8px 4px;
  border: 0; border-radius: 12px; background: none; color: var(--text); font: inherit;
  text-align: center; cursor: pointer;
}
.person-card:hover { text-decoration: none; background: var(--panel); }
.person-card .face {
  display: flex; align-items: center; justify-content: center; width: 96px; height: 96px;
  border-radius: 50%; overflow: hidden; background: var(--panel); color: var(--muted);
}
.person-card .face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.person-card .face svg { width: 40px; height: 40px; fill: none; stroke: currentColor; stroke-width: 1.5; }
.person-card .name { font-weight: 600; font-size: 14px; overflow-wrap: anywhere; }
.person-card .meta { color: var(--muted); font-size: 12px; }
.person-card.unnamed .name { color: var(--muted); font-weight: 400; }
.person-card.hidden-group .face img { filter: grayscale(1); opacity: .6; }
.people-numbers { margin-top: 26px; }
.people pre { background: var(--panel); padding: 10px 14px; border-radius: 8px; overflow-x: auto; }

.who { display: flex; gap: 10px; align-items: center; margin: 8px 0 2px; }
.who h1 { margin: 0; }
.who .face { width: 56px; height: 56px; border-radius: 50%; overflow: hidden; flex: none; background: var(--panel); }
.who .face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.name-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; max-width: 680px; margin-bottom: 6px; }
.name-row .name-focus { color: var(--muted); font-size: 14px; cursor: pointer; }
.name-row input {
  flex: 1; min-width: 200px; font: inherit; font-size: 17px; padding: 9px 14px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--bg); color: var(--text);
}
.name-row input:focus { outline: 2px solid var(--accent); border-color: transparent; }
.name-row .icon { color: var(--bg); background: var(--accent); flex: none; }
.guess {
  display: inline-flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px; border-radius: 999px;
  border: 1px dashed var(--accent); background: var(--accent-soft); color: var(--text);
  font: inherit; font-size: 14px; cursor: pointer;
}
.guess img { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; }
.face-grid { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); margin-top: 12px; padding-bottom: 110px; }
.face-card {
  position: relative; display: block; aspect-ratio: 1; overflow: hidden; cursor: pointer;
  border: 3px solid var(--keep); border-radius: 12px; background: var(--panel);
}
.face-card input { position: absolute; opacity: 0; pointer-events: none; }
.face-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.face-card:has(input:checked) { border-color: var(--drop); }
.face-card:has(input:checked) img { opacity: .35; }
.face-card:has(input:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; }
.face-card .num {
  position: absolute; left: 5px; top: 5px; min-width: 22px; height: 22px; padding: 0 5px;
  border-radius: 999px; display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 12px; color: #fff; background: rgba(0, 0, 0, .55);
}
.face-card .x {
  position: absolute; right: 5px; top: 5px; width: 22px; height: 22px; border-radius: 50%;
  display: none; align-items: center; justify-content: center;
  color: var(--on-keep); background: var(--drop); font-weight: 700;
}
.face-card:has(input:checked) .x { display: flex; }
.face-card .when {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 2px 6px; font-size: 11px; color: #fff;
  background: linear-gradient(transparent, rgba(0, 0, 0, .6));
}
/* The tally counts the faces with CSS counters, without JavaScript. */
.face-form { counter-reset: keep drop; }
.face-card input:checked { counter-increment: drop; }
.face-card input:not(:checked) { counter-increment: keep; }
.face-tally { font-size: 14px; }
.face-tally::before { content: counter(keep) " bekommen den Namen · " counter(drop) " nicht"; }
.face-form:not(:has(.face-card input:not(:checked))) .face-apply { opacity: .45; pointer-events: none; }

.person-head .title-row .face { width: 56px; height: 56px; border-radius: 50%; overflow: hidden; flex: none; }
.person-head .title-row .face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.person-head .to-people { font-size: 14px; justify-self: start; }
.person-head .maybe-link {
  padding: 5px 12px; border-radius: 999px; background: var(--accent-soft); color: var(--accent);
  font-size: 14px; font-weight: 600;
}

/* The face boxes lie exactly over the fitted photo: as wide as the stage
   allows at the photo's ratio, never above 100 %. */
.canvas { container-type: size; }
.face-layer {
  position: absolute; inset: 0; margin: auto; z-index: 1; pointer-events: none;
  width: min(100cqw, 100cqh * var(--ratio), var(--w));
  height: min(100cqh, 100cqw / var(--ratio), var(--h));
}
.face-box {
  position: absolute; display: none; pointer-events: auto; border: 2px solid var(--mustard);
  border-radius: 8px; box-shadow: 0 0 0 1px rgba(0, 0, 0, .4); cursor: pointer;
}
.face-box.unknown { border-style: dashed; }
.viewer:has(#faces:checked) .face-box, .face-box.lit { display: block; }
.face-box.lit { border-color: #fff; border-width: 3px; }
.viewer:has(#zoom:checked) .face-layer { display: none; }
.face-box .tag {
  position: absolute; left: -2px; top: calc(100% + 4px); white-space: nowrap; padding: 1px 8px;
  border-radius: 999px; font-size: 12px; font-weight: 600; color: #1F2A2A; background: var(--mustard);
}
.face-box:hover { text-decoration: none; }
.faces-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.faces-toggle:has(input:checked) { background: var(--accent); }
.faces-toggle:has(input:focus-visible) { outline: 2px solid #fff; }
.people-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.people-chips li {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 4px 3px 3px; border-radius: 999px;
  background: var(--panel); border: 1px solid var(--line); font-size: 14px;
}
.people-chips li.unknown { border-style: dashed; }
.people-chips img { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; }
.people-chips form { display: contents; }
.people-chips a { color: var(--text); }
.people-chips button.remove {
  width: 22px; height: 22px; border: 0; border-radius: 50%; background: none;
  color: var(--muted); cursor: pointer; font-size: 15px; line-height: 1;
}
.people-chips button.remove:hover { background: var(--line); color: var(--text); }
.people-chips .name-face { color: var(--accent); cursor: pointer; padding-right: 4px; }
.people-chips .face-name input {
  width: 9em; font: inherit; font-size: 13px; padding: 3px 8px; margin-right: 2px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--bg); color: var(--text);
}
@media (max-width: 760px) {
  .people-grid { grid-template-columns: repeat(3, 1fr); gap: 10px 4px; }
  .person-card .face { width: 80px; height: 80px; }
  .face-grid { grid-template-columns: repeat(2, 1fr); gap: 6px; padding-bottom: 150px; }
}
/* Portrait screens wider than a phone (an iPad held upright, a narrow
   window): the info goes below the photo, as on phones. The stage is as
   high as the photo (--shape, height / width), at most three quarters of
   the screen, so the info starts within sight. */
@media (orientation: portrait) and (min-width: 761px) {
  .viewer { grid-template-columns: 1fr; height: auto; }
  .stage { height: min(100vw * var(--shape, .75), 75vh); min-height: 320px; }
  .info { border-left: 0; border-top: 1px solid var(--line); }
}
/* Phones: the detail view without the top bar (the search is one step
   back); "←" and the icons share the space above the photo. The icons wrap
   into a second row when there are more than fit into one (a hidden
   overflow, scrolling sideways, was not noticed); the stage is as high as
   the photo (--shape, height / width), at most the screen, so the info
   follows right below. */
@media (max-width: 760px) {
  body:has(.viewer) > .topbar { display: none; }
  .stage {
    --icon: 36px;
    --bar: calc(var(--icon) + 16px);
    height: calc(var(--bar) + min(100vw * var(--shape, .75), 100dvh - var(--bar) - 48px));
    min-height: calc(var(--bar) + 160px);
  }
  .stage .canvas, .stage .player { top: var(--bar); }
  .stage > img { position: absolute; top: var(--bar); left: 0; width: 100%; height: calc(100% - var(--bar)); }
  .stage .back {
    top: 8px; left: 8px; width: 36px; height: 36px; padding: 0;
    display: flex; align-items: center; justify-content: center; font-size: 20px;
  }
  .stage .back .label { display: none; }
  .stage .actions {
    top: 8px; left: 52px; right: 0; gap: 4px; padding-right: 8px;
    justify-content: flex-end; flex-wrap: wrap;
  }
  .stage .actions .icon { width: var(--icon); height: var(--icon); flex: none; }
  /* Seven icons or more do not fit into one row on a narrow phone. */
  .stage:has(.actions > :nth-child(7)) { --bar: calc(2 * var(--icon) + 20px); }
  .stage .step {
    top: calc(50% + var(--bar) / 2); padding: 6px 10px; font-size: 24px;
    background: rgba(0, 0, 0, .25);
  }
  .stage .step.previous { left: 6px; }
  .stage .step.next { right: 6px; }
}
/* Touch screens have no keyboard: no "?" button for the shortcuts. */
@media (hover: none) and (pointer: coarse) {
  button.icon.help, .ed-btn.help { display: none; }
}

/* Signing in (auth.py): the account button in the top bar and its menu. */
.account { margin-left: auto; flex: none; }
.avatar {
  width: 36px; height: 36px; border-radius: 50%; border: 0; padding: 0; cursor: pointer; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--bg); font: inherit; font-weight: 700; font-size: 14px;
}
.avatar.small { width: 30px; height: 30px; font-size: 12px; cursor: default; }
.avatar { overflow: hidden; }
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar.role-member { background: var(--accent); color: var(--on-accent); }
.avatar.role-guest { background: var(--slate); color: #fff; }
.avatar.role-waiting, .avatar.role-blocked { background: var(--muted); color: var(--bg); }
.account-menu {
  position: fixed; inset: 64px 16px auto auto; margin: 0; width: 280px; padding: 8px;
  color: var(--text); background: var(--bg); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
}
.account-menu .who {
  display: flex; gap: 10px; align-items: center; padding: 6px 6px 10px;
  margin-bottom: 6px; border-bottom: 1px solid var(--line);
}
.account-menu .who b { display: block; overflow-wrap: anywhere; }
.account-menu .who div > span { color: var(--muted); font-size: 13px; overflow-wrap: anywhere; }
.account-menu form { margin: 0; }
.account-menu a, .account-menu button {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 6px;
  border: 0; border-radius: 8px; background: none; color: var(--text);
  font: inherit; font-size: 14px; text-align: left; cursor: pointer;
}
.account-menu a:hover, .account-menu button:hover { background: var(--accent-soft); text-decoration: none; }
.account-menu kbd { margin-left: auto; }
.account-menu a.account-delete-link { color: var(--danger); }
/* The link at the end of "Einstellungen": an icon at text size. */
a.account-delete-link:not(.button) { display: inline-flex; gap: 6px; align-items: center; color: var(--danger); }
a.account-delete-link svg { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.account-menu svg {
  width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.role {
  display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 12px; font-weight: 600;
  color: var(--accent); background: var(--accent-soft);
}
.role.role-member { color: var(--teal-ink); background: var(--teal-soft); }
.role.role-guest { color: var(--slate-ink); background: var(--slate-soft); }
.role.role-waiting { color: var(--mustard-ink); background: var(--mustard-soft); }
.role.role-blocked { color: var(--coral-ink); background: var(--coral-soft); }
/* The plan of the viewer's library (plans.py), beside the role. */
.role.role-plan { color: var(--mustard-ink); background: var(--mustard-soft); }

/* The sign-in page and the page for accounts that wait. */
.login {
  min-height: calc(100vh - 60px); display: grid; place-items: center; padding: 24px 16px;
  background: radial-gradient(circle at 30% 20%, var(--accent-soft), transparent 60%), var(--bg);
}
.login-card {
  width: min(420px, 100%); padding: 32px 28px; display: grid; gap: 14px; text-align: center;
  background: var(--bg); border: 1px solid var(--line); border-radius: 18px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, .08);
}
.login-card img { height: 36px; width: auto; }
.login-card h1 { margin: 0; font-size: 21px; }
.login-card p { margin: 0; color: var(--muted); line-height: 1.45; }
.login-card form { margin: 0; }
.login-card .button { justify-content: center; width: 100%; padding: 11px 16px; font-size: 16px; }
.login-card .button kbd { font-size: 11px; background: none; border-color: currentColor; color: inherit; opacity: .8; }
.login-card .fine { font-size: 12px; }
.login-card .notice { color: var(--text); }
.login-error { color: var(--coral-ink) !important; background: var(--coral-soft); padding: 8px 10px; border-radius: 8px; }

/* "Nutzer und Freigaben" */
.users-page { max-width: 980px; }
.users-page h2 { margin: 24px 0 8px; font-size: 15px; }
.users-page .lead { margin: 0 0 8px; color: var(--muted); max-width: 70ch; }
.users-page .muted { color: var(--muted); }
.pending {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 12px 14px; margin-bottom: 8px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
}
.pending .person { flex: 1; min-width: 180px; }
.pending .since { color: var(--muted); font-size: 13px; }
.pending form { margin: 0; }
.pending .button kbd { font-size: 11px; background: none; border-color: currentColor; color: inherit; opacity: .8; }
.person { display: flex; align-items: center; gap: 10px; }
.person div > span { display: block; color: var(--muted); font-size: 12px; overflow-wrap: anywhere; }
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; }
table.users { width: 100%; min-width: 560px; border-collapse: collapse; font-size: 14px; }
table.users th {
  padding: 10px 12px; text-align: left; font-size: 12px; font-weight: 600; color: var(--muted);
  border-bottom: 1px solid var(--line);
}
table.users td { padding: 10px 12px; vertical-align: middle; border-bottom: 1px solid var(--line); }
table.users tr:last-child td { border-bottom: 0; }
table.users tr.changed td { background: var(--accent-soft); }
.role-switch { display: inline-flex; margin: 0; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; }
.role-switch button {
  padding: 4px 10px; border: 0; background: none; color: var(--muted);
  font: inherit; font-size: 13px; cursor: pointer;
}
.role-switch button + button { border-left: 1px solid var(--line); }
.role-switch button:hover { background: var(--panel); color: var(--text); }
.role-switch button.on { background: var(--accent); color: var(--bg); font-weight: 600; }
.role-switch button.on.role-blocked { background: var(--danger-bg); color: var(--on-danger); }
/* Sharing an album with guests */
.shared { display: inline-flex; gap: 5px; align-items: center; color: var(--muted); font-size: 13px; }
.shared svg { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; }
.album-card .shared { margin-top: -3px; font-size: 12px; }
a.shared:hover { color: var(--text); }
.share-row.changed { background: var(--accent-soft); }
.share-row .toggle {
  padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px; background: none;
  color: var(--muted); font: inherit; font-size: 13px; cursor: pointer;
}
.share-row .toggle:hover { color: var(--text); background: var(--bg); }
.share-row .toggle.on { background: var(--accent); border-color: var(--accent); color: var(--bg); font-weight: 600; }
.share-row .unshare { width: 32px; height: 32px; color: var(--muted); background: none; }
.share-row .unshare:hover { color: var(--on-danger); background: var(--danger-bg); }
.share-add .choices { display: flex; gap: 16px; flex-wrap: wrap; margin: 0 0 10px; font-size: 14px; }
.share-add .choices label { display: inline-flex; gap: 6px; align-items: center; }
.share-add .invite { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 6px; }
.share-add .invite label { font-size: 14px; font-weight: 600; }
.share-add .invite input { flex: 1 1 240px; min-width: 0; font: inherit; padding: 8px 12px; border: 1px solid var(--line); border-radius: 999px; background: var(--bg); color: var(--text); }
.share-add .invite input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.share-add h3 { font-size: 15px; margin: 18px 0 6px; }
.share-add .small { font-size: 13px; }
.share-add .button svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; }
.share-page h2 small.guest-count { font-weight: 400; color: var(--muted); font-size: 14px; margin-left: 8px; }
.invite-form .choices { display: flex; gap: 16px; flex-wrap: wrap; margin: 0 0 10px; font-size: 14px; }
.invite-form .choices label { display: inline-flex; gap: 6px; align-items: center; }
.invite-form .invite-link svg, .invite-copy svg, .share-page .person .avatar svg, .invite-album svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2;
}
.invite-link-made { margin: 0 0 14px; padding: 12px; border-radius: 12px; background: var(--accent-soft); }
.invite-link-made label { display: block; font-size: 14px; margin-bottom: 6px; }
.invite-copy { display: flex; gap: 8px; align-items: center; }
.invite-copy input { flex: 1 1 auto; min-width: 0; font-family: ui-monospace, monospace; font-size: 13px; }
.invite-card .invite-album { display: flex; gap: 8px; align-items: center; font-weight: 700; }
.invite-actions { display: flex; flex-direction: column; gap: 10px; margin: 16px 0; }
/* "Warteliste": the website's waiting list (interest.py) */
.waitlist-page .albums-head .button kbd { font-size: 11px; background: none; border-color: currentColor; color: inherit; opacity: .8; }
.pending.changed { background: var(--accent-soft); }
.pending.unconfirmed { background: none; }
.pending .wish { flex-basis: 100%; margin: 0; font-size: 13px; color: var(--muted); overflow-wrap: anywhere; white-space: pre-line; }
.waitlist-counts { display: flex; flex-wrap: wrap; gap: 12px; }
.waitlist-counts table.users { width: auto; min-width: 220px; border: 1px solid var(--line); border-radius: 12px; border-collapse: separate; border-spacing: 0; }
.interest-card > a { justify-self: center; }
.interest-card b { color: var(--text); overflow-wrap: anywhere; }
/* The contact form of the website once more, when a message came back (contact.py) */
.contact-card { width: min(520px, 100%); }
.contact-card form { display: grid; gap: 6px; text-align: left; }
.contact-card label { font-weight: 700; margin-top: 8px; }
.contact-card .req, .contact-card .opt { font-weight: 400; color: var(--muted); }
.contact-card input[type=email], .contact-card input[type=text], .contact-card textarea {
  width: 100%; padding: 10px 12px; font-size: 16px; color: var(--text); background: var(--bg);
  border: 1px solid var(--muted); border-radius: 10px;
}
.contact-card textarea { resize: vertical; }
.contact-card input:focus, .contact-card textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.contact-card form .button { margin-top: 12px; }
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.footer a { color: inherit; }

/* The privacy notice of the app (privacy.html, CS-89): text to read. */
.legal { max-width: 760px; margin: 0 auto; padding: 32px 16px 16px; line-height: 1.55; }
.legal-logo img { height: 36px; width: auto; }
.legal h1 { font-size: 26px; margin: 20px 0 12px; }
.legal h2 { font-size: 18px; margin: 28px 0 8px; }
.legal li { margin: 4px 0; }
.legal a:not(.button) { color: var(--accent); }
.legal-draft, .legal .ph { background: var(--mustard-soft); color: var(--mustard-ink); }
.legal-draft { padding: 10px 14px; border-radius: 10px; }
.legal .ph { padding: 0 4px; border-radius: 4px; }
.legal-table { overflow-x: auto; }
.legal-table table { width: 100%; min-width: 560px; border-collapse: collapse; font-size: 14px; }
.legal-table th { text-align: left; padding: 8px 10px; border-bottom: 2px solid var(--line); }
.legal-table td { padding: 8px 10px; vertical-align: top; border-bottom: 1px solid var(--line); }
.legal-table code { white-space: nowrap; }
.legal .back { position: static; display: inline-flex; gap: 6px; margin-top: 16px; }
.legal .back kbd { font-size: 11px; background: none; border-color: currentColor; color: inherit; opacity: .8; }
@media (max-width: 600px) {
  /* Phones: each row a block, each cell with its column's name. */
  .legal-table table { min-width: 0; }
  .legal-table thead { display: none; }
  .legal-table tr, .legal-table td { display: block; }
  .legal-table tr { padding: 8px 0; border-bottom: 1px solid var(--line); }
  .legal-table td { padding: 2px 0; border: 0; }
  .legal-table td::before { content: attr(data-label) ": "; font-weight: 700; }
  .legal-table code { white-space: normal; }
}
.legend { display: grid; grid-template-columns: auto 1fr; gap: 6px 10px; margin: 14px 0 0; font-size: 13px; color: var(--muted); }
.legend dd { margin: 0; }
@media (max-width: 760px) {
  .account-menu { inset: 60px 8px auto auto; }
}

/* Memories: "An diesem Tag" above the gallery, a card per earlier year. */
.layout > .content { min-width: 0; }
.collections .history svg { stroke: var(--accent); }
.memories { min-width: 0; margin: 4px 0 18px; padding: 12px 14px 14px; border-radius: 12px; background: var(--panel); }
.memories-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.memories-head h1 { margin: 0 6px 0 0; font-size: 20px; }
.memories-head .day { color: var(--muted); font-size: 14px; }
.memories-head .spacer { flex: 1; }
.memories-head .icon { width: 30px; height: 30px; flex: none; background: none; color: var(--muted); }
.memories-head .icon:hover { background: var(--accent-soft); color: var(--text); }
.memories-head .icon svg { width: 16px; height: 16px; }
.memories-head .memories-today {
  font-size: 13px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line); color: var(--text);
}
.memories-head .memories-today:hover { text-decoration: none; background: var(--accent-soft); }
.memory-cards { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 4px; scroll-snap-type: x proximity; }
.memory-card {
  position: relative; flex: none; width: 150px; aspect-ratio: 3 / 4; border-radius: 10px; overflow: hidden;
  scroll-snap-align: start; color: #fff; background: var(--line);
}
.memory-card:hover { text-decoration: none; }
.memory-card img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .2s; }
.memory-card:hover img { transform: scale(1.04); }
.memory-card .shade { position: absolute; inset: 0; background: linear-gradient(transparent 45%, rgba(0, 0, 0, .65)); }
.memory-card .ago { position: absolute; left: 10px; right: 8px; bottom: 26px; font-weight: 700; font-size: 16px; }
.memory-card .meta { position: absolute; left: 10px; bottom: 8px; font-size: 12px; opacity: .9; }
.memory-card kbd {
  position: absolute; top: 7px; left: 7px; font-size: 11px; padding: 1px 5px; border: 0; border-radius: 5px;
  background: rgba(0, 0, 0, .45); color: #fff;
}
.memory-card.current { outline: 3px solid var(--accent); outline-offset: -3px; }
.memories .empty { color: var(--muted); margin: 4px 0; }
@media (max-width: 700px) {
  .memory-card { width: 118px; }
  .memories-head { row-gap: 0; }
  .memories-head h1 { font-size: 18px; }
  /* The day on a line of its own, so the arrows stay next to the title. */
  .memories-head .day { order: 1; flex-basis: 100%; margin-top: -2px; font-size: 13px; }
}

/* Image editor (editor.html): fills the window, always dark like the stage. */
.editor-page {
  --ed-bg: #111717; --ed-panel: #1F2A2A; --ed-line: #3C4D4B; --ed-text: #FDF0D5;
  --ed-muted: #C9C2AE; --ed-accent: #5BB5A7;
  height: 100vh; height: 100dvh; overflow: hidden; background: var(--ed-bg);
}
.editor-defs { position: absolute; }
.editor {
  height: 100%; display: grid; grid-template-columns: 1fr 320px; grid-template-rows: auto minmax(0, 1fr);
  background: var(--ed-bg); color: var(--ed-text);
}
.ed-top {
  grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 12px; border-bottom: 1px solid var(--ed-line);
}
.ed-title { font-weight: 600; margin-right: auto; font-size: 14px; min-width: 0; overflow-wrap: anywhere; }
.ed-title small { display: block; color: var(--ed-muted); font-weight: 400; font-size: 12px; }
.ed-btn {
  display: inline-flex; gap: 6px; align-items: center; border: 1px solid var(--ed-line);
  background: var(--ed-panel); color: var(--ed-text); border-radius: 999px; padding: 6px 12px;
  cursor: pointer; font: inherit; font-size: 14px; text-decoration: none;
}
.ed-btn:hover { border-color: var(--ed-muted); text-decoration: none; }
.ed-btn:disabled { opacity: .4; cursor: default; }
.ed-btn.square { padding: 6px; border-radius: 8px; }
.ed-btn.primary { background: var(--ed-accent); border-color: var(--ed-accent); color: #1F2A2A; font-weight: 600; }
.ed-btn svg, .ed-tool svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.editor kbd { background: transparent; border-color: var(--ed-line); color: var(--ed-muted); }
.ed-btn.primary kbd { color: #1F2A2A; border-color: rgba(0, 0, 0, .3); }
.editor :focus-visible { outline: 2px solid var(--ed-accent); outline-offset: 2px; }
.ed-stage {
  position: relative; min-height: 0; overflow: hidden; display: grid; place-items: center;
  padding: 28px; user-select: none; touch-action: none;
}
.ed-frame { position: relative; overflow: hidden; }
.ed-frame.cropping { overflow: visible; }
.ed-canvas { position: absolute; overflow: hidden; }
.ed-canvas img {
  position: absolute; left: 50%; top: 50%; max-width: none; display: block;
  transform-origin: 50% 50%; pointer-events: none;
}
.ed-vignette { position: absolute; inset: 0; pointer-events: none; }
.ed-cropbox {
  position: absolute; cursor: move; box-shadow: 0 0 0 9999px rgba(0, 0, 0, .6);
  outline: 1px solid rgba(255, 255, 255, .9);
}
.ed-grid {
  position: absolute; inset: 0; pointer-events: none;
  --line: rgba(255, 255, 255, .45);
  background:
    linear-gradient(var(--line), var(--line)) calc(100% / 3) 0 / 1px 100% no-repeat,
    linear-gradient(var(--line), var(--line)) calc(200% / 3) 0 / 1px 100% no-repeat,
    linear-gradient(var(--line), var(--line)) 0 calc(100% / 3) / 100% 1px no-repeat,
    linear-gradient(var(--line), var(--line)) 0 calc(200% / 3) / 100% 1px no-repeat;
}
.ed-handle { position: absolute; width: 22px; height: 22px; }
.ed-handle::before { content: ""; position: absolute; inset: 7px; background: #fff; border-radius: 2px; }
.ed-handle[data-h="nw"] { left: -11px; top: -11px; cursor: nwse-resize; }
.ed-handle[data-h="ne"] { right: -11px; top: -11px; cursor: nesw-resize; }
.ed-handle[data-h="sw"] { left: -11px; bottom: -11px; cursor: nesw-resize; }
.ed-handle[data-h="se"] { right: -11px; bottom: -11px; cursor: nwse-resize; }
.ed-handle[data-h="n"] { left: calc(50% - 11px); top: -11px; cursor: ns-resize; }
.ed-handle[data-h="s"] { left: calc(50% - 11px); bottom: -11px; cursor: ns-resize; }
.ed-handle[data-h="w"] { top: calc(50% - 11px); left: -11px; cursor: ew-resize; }
.ed-handle[data-h="e"] { top: calc(50% - 11px); right: -11px; cursor: ew-resize; }
.ed-cropbox.locked .ed-handle:is([data-h="n"], [data-h="s"], [data-h="w"], [data-h="e"]) { display: none; }
.ed-compare-tag {
  position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 3;
  background: rgba(0, 0, 0, .7); color: #fff; font-size: 12px; border-radius: 999px; padding: 3px 10px;
}
.ed-panel { border-left: 1px solid var(--ed-line); background: var(--ed-panel); display: flex; flex-direction: column; min-height: 0; }
.ed-tools { display: grid; grid-template-columns: repeat(3, 1fr); border-bottom: 1px solid var(--ed-line); }
.ed-tool {
  display: grid; justify-items: center; gap: 3px; padding: 10px 4px 8px; cursor: pointer;
  background: none; border: 0; border-bottom: 2px solid transparent; color: var(--ed-muted); font: inherit; font-size: 13px;
}
.ed-tool svg { width: 22px; height: 22px; }
.ed-tool[aria-selected="true"] { color: var(--ed-text); border-bottom-color: var(--ed-accent); }
.ed-pane { padding: 16px; overflow-y: auto; display: flex; flex-direction: column; gap: 18px; min-height: 0; }
.editor-page [hidden] { display: none !important; }
.ed-pane h3 {
  margin: 0 0 8px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--ed-muted);
}
.ed-row-buttons, .ed-ratios { display: flex; flex-wrap: wrap; gap: 8px; }
.ed-ratio {
  border: 1px solid var(--ed-line); background: none; color: var(--ed-text); border-radius: 999px;
  padding: 4px 10px; font: inherit; font-size: 13px; cursor: pointer;
}
.ed-ratio[aria-pressed="true"] { background: var(--ed-accent); border-color: var(--ed-accent); color: #1F2A2A; }
.ed-slider { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; align-items: center; padding: 6px 8px; border-radius: 8px; }
.ed-slider.active { background: rgba(91, 181, 167, .14); }
.ed-slider.off { opacity: .45; }
.ed-slider label { font-size: 14px; display: flex; gap: 8px; align-items: center; }
.ed-slider output { font-size: 13px; color: var(--ed-muted); font-variant-numeric: tabular-nums; min-width: 3.5em; text-align: right; }
.ed-slider input { grid-column: 1 / -1; width: 100%; accent-color: var(--ed-accent); }
.ed-filters { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px 8px; }
.ed-fbtn {
  display: grid; gap: 4px; padding: 0; background: none; border: 0; cursor: pointer;
  color: var(--ed-muted); font: inherit; font-size: 12px; text-align: center;
  min-width: 0; line-height: 1.25; align-content: start;
}
.ed-group { border-top: 1px solid var(--ed-line); padding-top: 10px; }
.ed-group summary {
  cursor: pointer; font-size: 13px; font-weight: 600; color: var(--ed-text);
  padding: 2px 0 8px; list-style-position: inside;
}
.ed-group summary small { font-weight: 400; color: var(--ed-muted); margin-left: 4px; }
.ed-group:not([open]) summary { padding-bottom: 0; }
/* Long names (e.g. of .cube files) wrap instead of widening the column. */
.ed-fbtn > span:last-child { overflow-wrap: anywhere; }
.ed-fthumb { position: relative; display: block; border-radius: 6px; overflow: hidden; outline: 2px solid transparent; outline-offset: 1px; }
.ed-fthumb img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.ed-fbtn[aria-pressed="true"] { color: var(--ed-text); }
.ed-fbtn[aria-pressed="true"] .ed-fthumb { outline-color: var(--ed-accent); }
.ed-hint { margin: 0; font-size: 12px; line-height: 1.45; color: var(--ed-muted); }
.ed-warning { margin: 0; font-size: 13px; color: #F08A70; }
.ed-pop { max-width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 48px); overflow-y: auto; }
.ed-pop[popover] {
  padding: 20px; border: 1px solid var(--line); border-radius: 12px; background: var(--bg); color: var(--text);
}
.ed-pop::backdrop { background: rgba(0, 0, 0, .45); }
.ed-pop h2 { margin: 0 0 12px; font-size: 17px; }
.ed-pop h3 { margin: 16px 0 6px; font-size: 14px; }
.ed-pop ul { padding-left: 18px; line-height: 1.5; font-size: 14px; }
.ed-save-name {
  font: 600 15px ui-monospace, SFMono-Regular, Menlo, monospace; overflow-wrap: anywhere;
  background: var(--panel); padding: 8px 10px; border-radius: 8px;
}
.ed-ini {
  max-height: 50vh; overflow: auto; font-size: 12px; line-height: 1.45;
  background: var(--panel); padding: 10px; border-radius: 8px;
}
.pop-actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }
.ed-flash {
  position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 50;
  background: var(--text); color: var(--bg); padding: 8px 14px; border-radius: 999px; font-size: 14px;
}
.ed-flash[hidden] { display: none; }
@media (max-width: 760px) {
  .editor { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr) auto; }
  .ed-stage { padding: 16px; }
  .ed-panel { border-left: 0; border-top: 1px solid var(--ed-line); max-height: 44vh; }
  .ed-top .lbl, .ed-top kbd { display: none; }
  .ed-filters { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* Portrait screens wider than a phone (an iPad held upright, a narrow
   window): the panel goes below the photo, as on phones. The photo keeps
   the larger part of the height and stays in view; the panel scrolls. */
@media (orientation: portrait) and (min-width: 761px) {
  .editor { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr) auto; }
  .ed-panel { border-left: 0; border-top: 1px solid var(--ed-line); max-height: 40vh; }
  .ed-filters { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
/* Holding a finger on the photo or on "Vergleichen" shows the original
   (editor.js): no text selection or link menu meanwhile. */
.ed-stage, #ed-compare { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
#ed-compare { touch-action: none; }

/* Versions of a photo in the detail view: the original and its edits. */
.versions { display: flex; flex-wrap: wrap; gap: 10px; }
.version { display: grid; gap: 4px; width: 110px; font-size: 12px; color: var(--muted); }
.version img { width: 110px; height: 74px; object-fit: cover; border-radius: 6px; display: block; }
.version.current img { outline: 2px solid var(--accent); outline-offset: 1px; }
.version span { overflow-wrap: anywhere; }
.made-from { font-size: 13px; color: var(--muted); margin: 4px 0 0; }

/* "Einstellungen" and setting a library up (library*.html). */
.library-page .path { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; overflow-wrap: anywhere; }
.library-facts { display: grid; grid-template-columns: max-content 1fr; gap: 12px 18px; margin: 18px 0; }
.library-facts dt { color: var(--muted); }
.library-facts dd { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.library-facts form { margin: 0; }
.library-facts .button kbd { font-size: 11px; background: none; border-color: currentColor; color: inherit; opacity: .8; }
/* A div, unlike the other notices (paragraphs): the same 1em above and
   below, so it does not touch the view switch. */
.notice.reading { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 1em 0; }
.notice.reading .job-bar { max-width: 260px; height: 8px; }
/* Links in a notice: an icon at text size (unstyled, an SVG fills the box). */
/* "Konto löschen", "Bibliothek zurücksetzen": signing in again comes next. */
.notice.sign-in-again { display: flex; gap: 10px; align-items: flex-start; margin: 16px 0; }
.notice.sign-in-again svg {
  flex: none; width: 20px; height: 20px; margin-top: 2px;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.notice-link { display: inline-flex; align-items: center; gap: 6px; }
.notice-link svg {
  width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
@media (max-width: 760px) {
  .library-facts { grid-template-columns: 1fr; gap: 4px; }
  .library-facts dd { margin-bottom: 10px; }
}

/* Photos others share (sharing.py): whose they are, and whose to see. */
/* A class of its own: .view-switch (gallery / map) would add its padding and
   gaps. One pill, the chosen part a rounded pill inside it. */
.whose-switch {
  display: inline-flex; gap: 2px; padding: 3px; margin: 0 0 12px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--panel);
}
.whose-switch button {
  font: inherit; font-size: 14px; padding: 5px 14px; border: 0; border-radius: 999px;
  background: transparent; color: var(--text); cursor: pointer;
}
.whose-switch button:hover { background: var(--accent-soft); }
.whose-switch button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.whose-switch button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tile-owner.avatar.small { position: absolute; top: 6px; left: 34px; z-index: 1; width: 24px; height: 24px; font-size: 11px; border: 2px solid var(--bg); pointer-events: none; }
.owner-line { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 14px; margin: 4px 0 10px; }
.albums-section { margin-top: 28px; }
.add-to { margin-top: 6px; }
.chip-add { font: inherit; font-size: 13px; border: 1px dashed var(--line); border-radius: 999px; padding: 3px 10px; background: none; color: var(--text); cursor: pointer; }
.chip-add .muted, .album-pop li button .owner { color: var(--muted); font-size: 12px; }
.album-pop li button .owner { white-space: nowrap; }
.share-page .toggle.add { font-weight: 600; }

/* Settings (settings.py): "Einstellungen" and "Einstellungen für alle".
   One row per setting: its name, its control, where its value comes from. */
.settings { border-top: 1px solid var(--line); margin-top: 20px; padding-top: 4px; }
.settings h2 { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px; }
.settings h2 small { font-weight: 400; color: var(--muted); font-size: 13px; }
.setting-row {
  display: grid; grid-template-columns: minmax(0, 15rem) minmax(0, 1fr) auto;
  gap: 6px 16px; align-items: center; padding: 8px 0;
}
.setting-row:target, .setting-row:focus-within { background: var(--panel); box-shadow: -8px 0 0 var(--panel), 8px 0 0 var(--panel); border-radius: 8px; }
.setting-label { font-weight: 600; min-width: 0; }
.setting-control { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0; min-width: 0; }
.setting-control input[type=number], .setting-control input[type=text] {
  font: inherit; color: var(--text); background: var(--bg); min-width: 0;
  border: 1px solid var(--line); border-radius: 8px; padding: 5px 10px;
}
.setting-control input[type=number] { width: 7rem; font-variant-numeric: tabular-nums; }
.setting-control input.short { width: 8rem; }
.setting-control input.wide { flex: 1 1 16rem; }
.setting-control .toggle {
  padding: 4px 12px; border: 1px solid var(--line); border-radius: 999px; background: none;
  color: var(--muted); font: inherit; font-size: 13px; cursor: pointer;
}
.setting-control .toggle.on { background: var(--accent); border-color: var(--accent); color: var(--bg); font-weight: 600; }
.button.small { padding: 4px 12px; font-size: 13px; gap: 6px; }
.button.small svg { width: 15px; height: 15px; }
.setting-origin { display: flex; align-items: center; justify-content: flex-end; gap: 4px; }
.setting-origin form { margin: 0; }
.origin { font-size: 12px; padding: 2px 8px; border-radius: 999px; white-space: nowrap; color: var(--muted); background: var(--panel); }
.origin-ini { color: var(--mustard-ink); background: var(--mustard-soft); }
.origin-set { color: var(--teal-ink); background: var(--teal-soft); }
.reset-setting { width: 28px; height: 28px; border: 0; border-radius: 50%; background: none; color: var(--accent); cursor: pointer; display: inline-grid; place-items: center; }
.reset-setting:hover { background: var(--accent-soft); }
.reset-setting svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.setting-hint { grid-column: 1 / -1; margin: -2px 0 0; color: var(--muted); font-size: 13px; max-width: 70ch; }
.setting-after { margin: 8px 0; padding: 8px 12px; border-radius: 10px; background: var(--accent-soft); font-size: 14px; }
.filter-choice fieldset { border: 0; padding: 0; margin: 10px 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: 6px 14px; }
.filter-choice legend { font-weight: 600; display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.filter-choice legend svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; }
.filter-choice label { display: flex; gap: 6px; align-items: center; }
.ini-list { display: grid; grid-template-columns: minmax(0, 12rem) minmax(0, 1fr); gap: 6px 16px; font-size: 14px; }
.ini-list dt { font-family: ui-monospace, Menlo, monospace; font-size: 13px; }
.ini-list dd { margin: 0; color: var(--muted); }
.settings details summary { cursor: pointer; font-weight: 600; padding: 10px 0; }
/* Folding sections, the table of contents, the search (CS-29). */
.settings > details > summary { list-style: none; display: flex; align-items: center; gap: 8px; }
.settings > details > summary::-webkit-details-marker { display: none; }
.settings > details > summary::before {
  content: ""; width: 8px; height: 8px; flex: none; margin: 0 4px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(-45deg); transition: transform .15s;
}
.settings > details[open] > summary::before { transform: rotate(45deg); }
.settings > details > summary h2 { margin: 0; }
/* Folding sections (settings pages): one line between them, close together. */
.settings:has(> details) { margin-top: 0; padding-top: 0; }
.settings > details { border-top: 0; padding: 0; }
.settings > details[open] { padding-bottom: 12px; }
.settings h3 { margin: 18px 0 4px; font-size: 16px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.settings h3 small { font-weight: 400; font-size: 13px; }
.settings-toc ol { list-style: none; margin: 12px 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.settings-toc a {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--text); text-decoration: none; font-size: 14px;
}
.settings-toc a:hover, .settings-toc a:focus-visible { background: var(--panel); }
.settings-toc a.has-changes { border-color: var(--accent); }
.settings-toc kbd { font-size: 11px; }
.settings-toc .count { font-size: 12px; padding: 0 6px; border-radius: 999px; color: var(--teal-ink); background: var(--teal-soft); }
.settings-search { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 8px; }
.settings-search input[type=search] {
  font: inherit; color: var(--text); background: var(--bg); flex: 1 1 14rem; min-width: 0;
  border: 1px solid var(--line); border-radius: 8px; padding: 5px 10px;
}
.settings-search-label { display: inline-grid; place-items: center; color: var(--muted); cursor: pointer; }
.settings-search-label svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.changed-toggle.on { background: var(--accent); border-color: var(--accent); color: var(--bg); }
.changed-toggle kbd { font-size: 11px; background: none; border-color: currentColor; color: inherit; }
/* "is-set", not "changed": .changed draws the mustard bar of edited fields. */
.setting-row.is-set .setting-label::after { content: " •"; color: var(--accent); }
.setting-fallback { font-size: 12px; white-space: nowrap; }
.origin-all { color: var(--teal-ink); background: var(--panel); border: 1px solid var(--teal-soft); }
.origin-plan { color: var(--mustard-ink); background: var(--panel); border: 1px solid var(--mustard-soft); }
.library-limits { border-collapse: collapse; width: 100%; font-size: 14px; }
.library-limits th, .library-limits td { text-align: left; vertical-align: top; padding: 8px 10px 8px 0; border-top: 1px solid var(--line); }
.library-limits thead th { border-top: 0; color: var(--muted); font-weight: 400; }
.library-limits td .setting-control input[type=text] { width: 6rem; }
.library-limits td .setting-control input[type=number] { width: 5rem; }
.library-limits td .setting-origin { justify-content: flex-start; margin-top: 4px; flex-wrap: wrap; }
.library-limits td > .muted { display: block; font-size: 12px; margin-top: 2px; }
.library-limits tr.is-set th::after { content: " •"; color: var(--accent); }
.table-scroll { overflow-x: auto; }
.ini-list code { font-size: 12px; margin-right: 2px; }
.ini-list code.ini-unset { opacity: .55; }
@media (max-width: 640px) {
  .setting-row { grid-template-columns: minmax(0, 1fr) auto; }
  .setting-row .setting-control { grid-column: 1 / -1; grid-row: 2; }
  .setting-hint { grid-row: 3; }
}
.icon.settings-menu { color: var(--text); background: var(--panel); }
/* The theme switch in the top bar (theme.js): it shows the current mode. */
.icon.theme-toggle { margin-left: auto; flex: none; color: var(--text); background: var(--panel); }
.icon.theme-toggle:hover { background: var(--accent-soft); }
.icon.theme-toggle + .account { margin-left: 0; }
.theme-toggle span { display: none; line-height: 0; }
.theme-toggle[data-mode="system"] .mode-system,
.theme-toggle[data-mode="light"] .mode-light,
.theme-toggle[data-mode="dark"] .mode-dark { display: block; }
/* On phones the switch moves into the account menu, as three buttons, so the
   search field has room; without an account menu it stays in the top bar. */
.account-menu .theme-choice { display: none; padding: 6px 6px 8px; }
.theme-choice > span { display: flex; align-items: center; color: var(--muted); font-size: 13px; }
.theme-choice .segments {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; margin-top: 6px;
  padding: 3px; border: 1px solid var(--line); border-radius: 999px;
}
.account-menu .theme-choice button { justify-content: center; padding: 0; height: 40px; border-radius: 999px; }
.account-menu .theme-choice button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); }
@media (max-width: 760px) {
  .topbar:has(.account) .theme-toggle { display: none; }
  .account-menu .theme-choice { display: block; }
}
.icon.settings-menu:hover { background: var(--accent-soft); }
.filter-choice .group-all { display: inline-flex; gap: .3rem; margin-left: .5rem; vertical-align: middle; }
/* "Eigene Filter" on "Einstellungen": upload, list, download, delete. */
.own-filters { margin-top: 20px; padding-top: 12px; border-top: 1px solid var(--line); }
.own-filters h3 { display: flex; align-items: center; gap: 8px; margin: 0 0 6px; font-size: 16px; }
.own-filters h3 svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; }
.own-filters h3 small { font-weight: 400; }
.own-filter-upload { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0; }
.own-filter-upload input[type=file] { max-width: 100%; font: inherit; font-size: 14px; color: var(--muted); }
/* "Dateien wählen" (U) is the button; the field only says what was chosen. */
.own-filter-upload input[type=file]::file-selector-button { display: none; }
.own-filters .button kbd { font-size: 11px; background: none; border-color: currentColor; color: inherit; opacity: .8; }
/* "Profilfoto" on "Einstellungen": the picture as it shows, then the form
   like the one of the own filters. */
.profile-picture { display: flex; gap: 20px; align-items: flex-start; }
.profile-picture .lead { margin-top: 0; }
.avatar.large { width: 96px; height: 96px; font-size: 40px; flex: none; cursor: default; }
.profile-picture-upload { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0; }
.profile-picture-upload input[type=file] { max-width: 100%; font: inherit; font-size: 14px; color: var(--muted); }
.profile-picture-upload input[type=file]::file-selector-button { display: none; }
.profile-picture .button kbd { font-size: 11px; background: none; border-color: currentColor; color: inherit; opacity: .8; }
@media (max-width: 760px) {
  .profile-picture { flex-direction: column; }
}
.own-filter-list { width: 100%; border-collapse: collapse; font-size: 14px; margin-top: 8px; }
.own-filter-list th { text-align: left; font-weight: 600; color: var(--muted); padding: 4px 8px 4px 0; }
.own-filter-list td { padding: 6px 8px 6px 0; border-top: 1px solid var(--line); overflow-wrap: anywhere; }
.own-filter-actions { display: flex; gap: 6px; justify-content: flex-end; }
.own-filter-actions form { margin: 0; }
@media (max-width: 640px) {
  .own-filter-list th:nth-child(2), .own-filter-list td:nth-child(2),
  .own-filter-list th:nth-child(4), .own-filter-list td:nth-child(4) { display: none; }
}

/* "Geräte" on "Meine Bibliothek" (devices.py). */
.device-list { width: 100%; border-collapse: collapse; font-size: 14px; margin-top: 8px; }
.device-list th { text-align: left; font-weight: 600; color: var(--muted); padding: 4px 8px 4px 0; }
.device-list td { padding: 6px 8px 6px 0; border-top: 1px solid var(--line); overflow-wrap: anywhere; vertical-align: middle; }
.device-list form { margin: 0; }
.device-list svg { width: 18px; height: 18px; vertical-align: middle; }
.device-name { display: flex; gap: 6px; align-items: center; }
.device-name input { flex: 1; min-width: 8em; }
@media (max-width: 640px) {
  .device-list th:nth-child(3), .device-list td:nth-child(3) { display: none; }
}

/* "Hochladen" (upload.html, upload.js). */
.upload-page { max-width: 1000px; }
.upload-form .drop {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 28px 16px 10px; border: 2px dashed var(--line); border-radius: 14px;
  color: var(--text); cursor: pointer; text-align: center;
}
.upload-form .drop.over { border-color: var(--accent); background: var(--accent-soft); }
.upload-form .drop svg {
  width: 40px; height: 40px; fill: none; stroke: var(--accent);
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
.upload-form .muted { color: var(--muted); }
.upload-pick, .upload-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin: 10px 0; }
.upload-actions { justify-content: flex-start; margin: 16px 0; }
.upload-form kbd { font-size: 11px; opacity: .7; }
.upload-limits { font-size: 13px; text-align: center; }
.upload-choices {
  display: grid; grid-template-columns: auto 1fr; gap: 8px 10px; align-items: center;
  max-width: 640px; margin: 16px 0;
}
.upload-choices input {
  font: inherit; padding: 7px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--bg); color: var(--text); min-width: 0;
}
.upload-choices .icon { color: var(--muted); }
.upload-choices .icon.add { color: var(--bg); }
.upload-choices .icon.add svg { width: 18px; height: 18px; }
.upload-tags { min-width: 0; }
.upload-tags .chips:not(:empty) { margin-top: 4px; }
.upload-tags .keyword-add { margin: 0; }
.upload-tags .chips:not(:empty) + .keyword-add { margin-top: 8px; }
.chips.editable li > span { padding: 4px 4px 4px 12px; }
.upload-choices .icon svg {
  width: 20px; height: 20px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.upload-bar { max-width: 640px; }
.upload-bar .meter { height: 10px; }
.upload-bar p { margin: 6px 0 0; font-size: 14px; }
.upload-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; }
.upload-list li {
  display: grid; align-items: center; gap: 2px 10px;
  grid-template-columns: 44px minmax(0, 1fr) auto auto;
  grid-template-areas: "thumb name size state" "thumb bar bar bar" "thumb message message message";
  padding: 6px 10px; border: 1px solid var(--line); border-radius: 10px;
}
.upload-list .thumb { grid-area: thumb; width: 44px; height: 44px; border-radius: 6px; background: var(--panel); overflow: hidden; }
.upload-list .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.upload-list .name { grid-area: name; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.upload-list .size { grid-area: size; color: var(--muted); font-size: 13px; }
.upload-list .state { grid-area: state; font-size: 13px; font-weight: 600; }
.upload-list .bar { grid-area: bar; height: 4px; border-radius: 999px; background: var(--line); overflow: hidden; }
.upload-list .bar span { display: block; height: 100%; background: var(--accent); }
.upload-list .message { grid-area: message; font-size: 13px; color: var(--muted); }
.upload-list .message:empty { display: none; }
.upload-list .state-saved .state { color: var(--keep); }
.upload-list .state-known .state { color: var(--muted); }
.upload-list .state-refused, .upload-list .state-failed { border-color: var(--danger); }
.upload-list .state-refused .state, .upload-list .state-failed .state { color: var(--danger); }
.upload-list .state-refused .bar, .upload-list .state-known .bar { visibility: hidden; }
.upload-hint { font-size: 13px; margin-top: 18px; }
.collections .upload svg { stroke: var(--accent); }
@media (max-width: 760px) {
  .upload-list li { grid-template-columns: 40px minmax(0, 1fr) auto; grid-template-areas: "thumb name state" "thumb bar bar" "thumb message message"; }
  .upload-list .size { display: none; }
}
.upload-page [hidden] { display: none !important; }
.upload-form .primary kbd { background: transparent; color: inherit; border-color: currentColor; }

/* Consent to face recognition (face_consent.html) */
.consent-state { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 8px; }
.consent-state.on { background: var(--accent-soft); }
.consent-state svg, .faces-consent svg { width: 20px; height: 20px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
a.faces-consent:not(.icon) { display: inline-flex; gap: 6px; align-items: center; }
a.faces-consent:not(.icon) svg { width: 16px; height: 16px; }
.icon.faces-consent.on { background: var(--accent); }
.consent-text ul { padding-left: 20px; }
.consent-text li { margin: 6px 0; }
.consent-check { display: flex; gap: 10px; align-items: flex-start; margin: 16px 0 0; cursor: pointer; }
.consent-check input { margin-top: 4px; }

/* Motion photos (motion.js): the mark on the tile, the video over the
   fitted photo in the detail view and over the tile under the mouse. */
.tile-motion {
  display: inline-flex; align-items: center; gap: 3px; padding: 2px 7px 2px 5px;
  border-radius: 999px; background: rgba(0, 0, 0, .55); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 16px; letter-spacing: .5px;
}
.tile-motion svg {
  width: 14px; height: 14px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.tile-clip {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .2s; pointer-events: none;
}
.tile.moving .tile-clip { opacity: 1; }
.canvas .motion-clip {
  position: absolute; inset: 0; margin: auto; z-index: 1; pointer-events: none;
  width: min(100cqw, 100cqh * var(--ratio), var(--w));
  height: min(100cqh, 100cqw / var(--ratio), var(--h));
  object-fit: cover; opacity: 0; transition: opacity .25s;
}
.viewer.moving .canvas .motion-clip { opacity: 1; }
.viewer:has(#zoom:checked) .canvas .motion-clip { display: none; }
.icon.motion-play .pause-icon, .viewer.moving .icon.motion-play .motion-icon { display: none; }
.viewer.moving .icon.motion-play .pause-icon { display: block; }
.viewer.moving .icon.motion-play { background: var(--accent); }
.icon.motion-play .pause-icon path { stroke-width: 3; }
@media (prefers-reduced-motion: reduce) {
  .tile-clip, .canvas .motion-clip { transition: none; }
}

/* "Anmeldung und Sicherheit" (security.html): passkeys, authenticator app.
   The QR code stays dark on white in both themes, so that cameras read it. */
.security-page .settings h3 { display: flex; align-items: center; gap: 8px; font-size: 16px; margin: 16px 0 8px; }
.security-page .settings h3 small { font-weight: 400; color: var(--muted); font-size: 13px; }
.security-page h3 svg, .security-list svg, .security-unlock-form p svg { width: 20px; height: 20px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.settings .lead a.account-security-link { display: inline-flex; gap: 6px; align-items: center; }
.settings .lead a.account-security-link svg { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.security-unlock-form { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; }
.security-unlock-form p { display: flex; align-items: center; gap: 8px; margin: 0; flex: 1 1 30ch; }
.security-list { list-style: none; padding: 0; margin: 0 0 12px; display: grid; gap: 8px; max-width: 560px; }
.security-list li { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; }
.security-list li span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.totp-setup { display: flex; flex-wrap: wrap; gap: 16px 24px; align-items: flex-start; margin: 8px 0 16px; }
.totp-qr { background: #fff; padding: 6px; border-radius: 8px; line-height: 0; }
.totp-qr svg { width: 200px; height: 200px; }
.totp-setup ol { margin: 0 0 12px; padding-left: 20px; max-width: 52ch; }
.totp-setup li { margin-bottom: 6px; }
.totp-secret { display: block; margin-top: 4px; font-size: 15px; letter-spacing: .08em; overflow-wrap: anywhere; user-select: all; }
.totp-form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.totp-form label { flex-basis: 100%; font-weight: 600; }
.security-page .primary kbd { background: transparent; color: inherit; border-color: currentColor; }
.totp-form input { font: inherit; font-size: 18px; letter-spacing: .15em; padding: 8px 10px; width: 10ch; }

/* Touch screens (a finger, not a mouse): everything that can be tapped is at
   least 48 px high, as Android asks, so a finger hits what it aims at. The
   mouse keeps the compact sizes above. Small round marks (the selection
   circle, a chip's ×) keep their look and get a larger invisible area. */
@media (pointer: coarse) {
  .icon, .icon.fold-all, .facets-head .close-sidebar, .place-bar .icon.close-bar,
  .discover .icon.close-bar, .album-head .icon, .icon.add, .view-actions .view-switch .icon,
  .stage .actions .icon, .geotag-form button.icon {
    width: 48px; height: 48px;
  }
  .stage { --icon: 48px; }
  .avatar:not(.small):not(.large) { width: 44px; height: 44px; }
  .facets-head { min-height: 48px; }
  .facets li a, .facet summary, .reset, .account-menu a, .account-menu button {
    min-height: 48px; align-items: center;
  }
  .facet summary { margin: 6px 0 0; }
  .chips { gap: 8px; }
  .chips a, .chips.editable li { min-height: 44px; display: flex; align-items: center; }
  .chips.editable button.remove { align-self: stretch; padding: 4px 14px 4px 8px; }
  .stars button { padding: 11px; }
  .stars { gap: 0; }
  .ai-toggle { width: 40px; height: 40px; left: 4px; }
  .search:has(.ai-toggle) input[type=search] { padding-left: 52px; }
  .search input { min-height: 48px; }
  .ed-btn { min-height: 48px; padding: 6px 16px; }
  .ed-btn.square { min-width: 48px; justify-content: center; }
  .ed-tool { min-height: 56px; }
  .whose-switch button { min-height: 44px; }
  .tile .pick::after { content: ""; position: absolute; inset: -12px; }
}

/* Deleting one's account (account_delete.html). */
.account-delete .delete-list { margin: 0 0 12px; padding-left: 20px; line-height: 1.6; }
.account-delete-form { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; max-width: 560px; }
.account-delete-form input[type=email], .account-delete-form input[type=text] { font: inherit; padding: 8px 10px; }
.account-delete-form .check { display: flex; gap: 8px; align-items: flex-start; }
.account-delete-form .check input { margin-top: 4px; }

/* "Bibliothek exportieren" (export.html) */
.export-parts { list-style: none; padding: 0; margin: 16px 0; display: grid; gap: 10px; }
.export-parts li { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; }
.export-parts .button { overflow-wrap: anywhere; }
.export-form label.export-changes { display: block; margin: 16px 0 0; cursor: pointer; }
.export-page .button kbd { font-size: 11px; background: none; border-color: currentColor; color: inherit; opacity: .8; }
.export-page .albums-head { align-items: center; }
a.export-link { display: inline-flex; gap: 6px; align-items: center; }
a.export-link svg { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
