/* ==========================================================================
   Family Cloud — visual system

   Three layers, in this order, and nothing may skip a layer:
     1. Palette      raw values, split by theme
     2. Semantics    --surface, --text, --accent … what components consume
     3. Components   every component styled ONCE, from semantics only

   The user controls theme, accent hue and density from Settings. Those set
   data-theme / data-accent / data-density on <html>; everything below reacts
   through tokens, so no component needs to know a setting exists.
   ========================================================================== */

/* ---- Accent hues (user-selectable) -------------------------------------- */
:root {
  --hue-blue: 222; --hue-indigo: 250; --hue-teal: 176;
  --hue-violet: 280; --hue-amber: 35; --hue-rose: 348;
  --hue-green: 145; --hue-cyan: 195; --hue-orange: 22; --hue-slate: 215;
  --h: var(--hue-blue);     /* overridden by [data-accent] */
  --sat: 78%;
}
:root[data-accent="indigo"] { --h: var(--hue-indigo); }
:root[data-accent="teal"]   { --h: var(--hue-teal);  --sat: 58%; }
:root[data-accent="violet"] { --h: var(--hue-violet); --sat: 62%; }
:root[data-accent="amber"]  { --h: var(--hue-amber); --sat: 80%; }
:root[data-accent="rose"]   { --h: var(--hue-rose);  --sat: 70%; }
:root[data-accent="green"]  { --h: var(--hue-green); --sat: 52%; }
:root[data-accent="cyan"]   { --h: var(--hue-cyan);  --sat: 68%; }
:root[data-accent="orange"] { --h: var(--hue-orange); --sat: 78%; }
:root[data-accent="slate"]  { --h: var(--hue-slate); --sat: 16%; }

/* ---- Density, text size, corners, depth (all user-selectable) ------------ */
:root {
  --row-h: 44px;
  --control-h: 30px;
  --gutter: 14px;
  --tile: 30px;
  --text-scale: 1;
  --radius-scale: 1;
  --depth-scale: 1;
  /* Shadows barely register on a dark background, so depth also drives border
     contrast and a surface lift. That is what makes flat and raised legible in
     dark mode, where a drop shadow alone is invisible. */
  --edge-strength: 1;
  --lift: 0.5;
}
:root[data-density="compact"] { --row-h: 34px; --control-h: 26px; --gutter: 10px; --tile: 22px; }
:root[data-density="roomy"]   { --row-h: 56px; --control-h: 34px; --gutter: 18px; --tile: 36px; }

:root[data-text="small"] { --text-scale: 0.92; }
:root[data-text="large"] { --text-scale: 1.12; }

:root[data-corners="sharp"] { --radius-scale: 0.25; }
:root[data-corners="soft"]  { --radius-scale: 1.7; }

:root[data-depth="flat"]   { --depth-scale: 0;   --edge-strength: 0;   --lift: 0; }
:root[data-depth="raised"] { --depth-scale: 2.6; --edge-strength: 1.8; --lift: 1; }

/* ---- Glass -------------------------------------------------------------
   Glass only reads as glass if something is behind it. These tokens drive the
   blur, the saturation lift that makes colours bloom through, and how much of
   the surface stays translucent. "off" collapses every one of them to a solid
   panel, so nothing depends on backdrop-filter being available. */
:root {
  --glass-blur: 18px;
  --glass-sat: 1.6;
  --glass-alpha: 0.72;    /* how opaque a glass surface is */
  --glass-edge: 0.10;     /* the lit top edge that suggests thickness */
  --ambient: 0.5;         /* strength of the colour behind the glass */
}
:root[data-glass="off"]    { --glass-blur: 0px;  --glass-sat: 1; --glass-alpha: 1;    --glass-edge: 0;    --ambient: 0; }
:root[data-glass="strong"] { --glass-blur: 30px; --glass-sat: 2; --glass-alpha: 0.55; --glass-edge: 0.18; --ambient: 1; }

/* ---- Semantics ----------------------------------------------------------
   Defined ONCE. light-dark() picks the value from `color-scheme`, so the theme
   setting is a single line (below) rather than a duplicated token table. */
:root {
  color-scheme: light dark;               /* follow the OS by default */

  --bg:            light-dark(#f7f7f6, #0e1014);
  --surface:       light-dark(#ffffff, #16191f);
  --elevated:      light-dark(#ffffff, #1d2128);
  --well:          light-dark(hsl(var(--h) 20% 96%), hsl(var(--h) 12% 14%));
  --rail:          light-dark(#f2f2f0, #121519);
  --border:        light-dark(hsl(220 14% 90%), hsl(220 10% 22%));
  --border-strong: light-dark(hsl(220 12% 82%), hsl(220 10% 32%));
  --text:          light-dark(#16181c, #e8eaef);
  --muted:         light-dark(#5c626b, #98a0ab);
  --subtle:        light-dark(#8b9199, #6b737e);

  --accent:        light-dark(hsl(var(--h) var(--sat) 52%), hsl(var(--h) var(--sat) 68%));
  --accent-hover:  light-dark(hsl(var(--h) var(--sat) 46%), hsl(var(--h) var(--sat) 74%));
  --accent-active: light-dark(hsl(var(--h) var(--sat) 41%), hsl(var(--h) var(--sat) 80%));
  --accent-weak:   light-dark(hsl(var(--h) var(--sat) 52% / 0.10), hsl(var(--h) var(--sat) 68% / 0.15));
  --accent-line:   light-dark(hsl(var(--h) var(--sat) 52% / 0.30), hsl(var(--h) var(--sat) 68% / 0.34));
  --on-accent:     light-dark(#ffffff, #0b0d10);

  --success:       light-dark(#14803c, #5fce85);
  --danger:        light-dark(#c2382e, #f0736a);
  --danger-hover:  light-dark(#a52d24, #f58a83);
  --danger-weak:   light-dark(hsl(4 70% 50% / 0.10), hsl(4 80% 62% / 0.16));
  --warning:       light-dark(#a8710a, #e0a94a);
  --scrim:         light-dark(rgba(11, 13, 18, 0.55), rgba(6, 8, 12, 0.65));
  --lb-control:      #1c2027;
  --lb-control-hover: #262b34;

  /* light-dark() resolves COLORS only. It cannot produce a number, so the
     shadow opacities and the bare hsl components below must come from ordinary
     per-theme rules — using light-dark() here made every shadow invalid, which
     is why "flat" and "raised" looked identical. */
  --shadow-hsl: 220 20% 12%;
  --shadow-strength: 1;
  /* Surfaces step further from the page as depth increases. */
  --surface-lift: color-mix(in srgb, var(--text) calc(var(--lift) * 5%), var(--surface));
  --border-lifted: color-mix(in srgb, var(--text) calc(var(--edge-strength) * 9%), var(--border));

  --shadow-1: 0 1px 2px hsl(var(--shadow-hsl) / calc(0.05 * var(--shadow-strength) * var(--depth-scale)));
  --shadow-2: 0 4px 12px -2px hsl(var(--shadow-hsl) / calc(0.10 * var(--shadow-strength) * var(--depth-scale))),
              0 2px 4px -2px hsl(var(--shadow-hsl) / calc(0.06 * var(--shadow-strength) * var(--depth-scale)));
  --shadow-3: 0 12px 32px -12px hsl(var(--shadow-hsl) / calc(0.24 * var(--shadow-strength) * var(--depth-scale))),
              0 2px 8px -4px hsl(var(--shadow-hsl) / calc(0.12 * var(--shadow-strength) * var(--depth-scale)));
  --edge: inset 0 1px 0 light-dark(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.04));

  --fs-xs:   calc(11px   * var(--text-scale));
  --fs-sm:   calc(12.5px * var(--text-scale));
  --fs-base: calc(13.5px * var(--text-scale));
  --fs-md:   calc(15px   * var(--text-scale));
  --fs-lg:   calc(17px   * var(--text-scale));
  --fs-xl:   calc(21px   * var(--text-scale));
  --fs-2xl:  calc(26px   * var(--text-scale));

  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px;
  --s-6: 24px; --s-8: 32px; --s-10: 40px; --s-12: 48px; --s-16: 64px;

  --r-xs: calc(5px  * var(--radius-scale));
  --r-sm: calc(7px  * var(--radius-scale));
  --r-md: calc(9px  * var(--radius-scale));
  --r-lg: calc(12px * var(--radius-scale));
  --r-xl: calc(16px * var(--radius-scale));
  --r-pill: 999px;

  --ring: 0 0 0 3px hsl(var(--h) var(--sat) 52% / 0.35);
  --topbar-h: 50px;
  --bottomnav-h: 56px;
}

/* The theme setting. color-scheme drives every light-dark() token above; the
   two numeric shadow values have to be set per theme by hand. */
:root[data-theme="light"] { color-scheme: light; --shadow-hsl: 220 20% 12%; --shadow-strength: 1; }
:root[data-theme="dark"]  { color-scheme: dark;  --shadow-hsl: 0 0% 0%;     --shadow-strength: 2.4; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --shadow-hsl: 0 0% 0%; --shadow-strength: 2.4; }
}

/* ---- Base --------------------------------------------------------------- */
* { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: var(--fs-base);
  line-height: 1.5;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  accent-color: var(--accent);
  -webkit-font-smoothing: antialiased;
}

body.centered {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-4);
}

h1, h2, h3 { line-height: 1.2; letter-spacing: -0.01em; margin: 0; }
a { color: var(--accent); }
.muted { color: var(--muted); }
.subtle { color: var(--subtle); }

:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r-sm); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
  .tile img { transform: none !important; }
}

/* ---- Buttons ------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  height: calc(var(--control-h) + 4px);
  padding: 0 var(--s-3);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
  transition: background 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease, transform 0.04s ease;
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.5; cursor: default; transform: none; }
.btn svg { width: 18px; height: 18px; flex: 0 0 auto; }

.btn-primary {
  color: var(--on-accent);
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 90%, #fff), var(--accent));
  box-shadow: var(--shadow-1), var(--edge);
}
.btn-primary:hover { background: var(--accent-hover); }
.btn-primary:active { background: var(--accent-active); box-shadow: var(--shadow-1); }

.btn-secondary {
  color: var(--text);
  background: var(--surface);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-1);
}
.btn-secondary:hover { background: var(--well); }

.btn-ghost { color: var(--muted); }
.btn-ghost:hover { background: var(--well); color: var(--text); }

.btn-danger {
  color: #fff;
  background: linear-gradient(180deg, color-mix(in srgb, var(--danger) 90%, #fff), var(--danger));
  box-shadow: var(--shadow-1), var(--edge);
}
.btn-danger:hover { background: var(--danger-hover); }

.btn-ghost.is-danger { color: var(--danger); }
.btn-ghost.is-danger:hover { background: var(--danger-weak); color: var(--danger); }

.btn-sm { height: var(--control-h); padding: 0 var(--s-3); font-size: var(--fs-sm); }
.btn-lg { height: 46px; padding: 0 var(--s-5); font-size: var(--fs-md); }
.btn-block { width: 100%; }
.form-submit { margin-top: var(--s-5); }
.btn-icon { width: 40px; height: 40px; padding: 0; border-radius: var(--r-md); }
.btn-icon.btn-sm { width: 32px; height: 32px; }

/* ---- Forms -------------------------------------------------------------- */
.field-label { display: block; font-size: var(--fs-sm); font-weight: 600; margin: var(--s-4) 0 var(--s-2); }
.field {
  width: 100%;
  height: 42px;
  padding: 0 var(--s-3);
  font: inherit;
  font-size: var(--fs-md);
  color: var(--text);
  background: var(--well);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.04);
}
.field::placeholder { color: var(--subtle); }
.field:focus-visible { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
.checkbox { display: flex; align-items: center; gap: var(--s-2); font-weight: 400; font-size: var(--fs-base); margin: var(--s-3) 0; }
.checkbox input { width: auto; height: auto; }

/* ---- Cards -------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: var(--s-6);
}
.card h2 { font-size: var(--fs-lg); font-weight: 600; margin-bottom: var(--s-4); }
.auth-card { width: 100%; max-width: 380px; border-radius: var(--r-xl); box-shadow: var(--shadow-2); }
.auth-card h1 { font-size: var(--fs-2xl); margin-bottom: var(--s-1); }

.row { display: flex; gap: var(--s-3); flex-wrap: wrap; }
.row.space-between { justify-content: space-between; align-items: center; }
.row.space-between h2 { margin: 0; }

/* ---- Top bar ------------------------------------------------------------ */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: var(--s-2);
  height: var(--topbar-h);
  padding: 0 var(--s-4);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-1);
}
.brand { display: flex; align-items: center; gap: var(--s-2); font-weight: 700; font-size: var(--fs-md); color: var(--text); text-decoration: none; margin-right: var(--s-3); }
.brand-mark {
  width: 28px; height: 28px; flex: 0 0 auto;
  display: grid; place-items: center;
  border-radius: var(--r-sm);
  color: #fff;
  background: linear-gradient(160deg, color-mix(in srgb, var(--accent) 80%, #fff), var(--accent));
  box-shadow: var(--shadow-1), var(--edge);
}
.brand-mark svg { width: 18px; height: 18px; }
.topbar .spacer { flex: 1; }
.section-title { font-weight: 700; font-size: var(--fs-md); }

.nav { display: flex; gap: var(--s-1); }
.nav-item {
  display: inline-flex; align-items: center; gap: var(--s-2);
  height: 38px; padding: 0 var(--s-3);
  font-size: var(--fs-sm); font-weight: 600;
  color: var(--muted); background: transparent;
  border: 1px solid transparent; border-radius: var(--r-pill);
  text-decoration: none; cursor: pointer;
}
.nav-item svg { width: 18px; height: 18px; }
.nav-item:hover { background: var(--well); color: var(--text); }
.nav-item[aria-current="page"] { background: var(--accent-weak); color: var(--accent); border-color: color-mix(in srgb, var(--accent) 22%, transparent); }

/* Avatar + account menu */
.avatar-wrap { position: relative; }
.avatar {
  width: 38px; height: 38px; padding: 0;
  display: grid; place-items: center;
  font-size: var(--fs-sm); font-weight: 700; color: var(--text);
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--r-pill); box-shadow: var(--shadow-1), var(--edge); cursor: pointer;
}
.avatar:hover { background: var(--well); }
.menu {
  position: absolute; right: 0; top: calc(100% + 8px);
  min-width: 232px; padding: var(--s-1);
  background: var(--elevated); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-3);
  z-index: 40;
}
.menu-head { padding: var(--s-2) var(--s-3); font-size: var(--fs-sm); color: var(--muted); }
.menu-head strong { color: var(--text); }
.menu-item {
  display: flex; align-items: center; gap: var(--s-2); width: 100%;
  padding: var(--s-2) var(--s-3); font: inherit; font-size: var(--fs-base);
  color: var(--text); background: transparent; border: none; border-radius: var(--r-sm);
  text-align: left; cursor: pointer;
}
.menu-item:hover { background: var(--well); }
.menu-item.is-danger { color: var(--danger); }
.menu-sep { height: 1px; margin: var(--s-1) var(--s-2); background: var(--border); border: none; }

/* Bottom nav (mobile only) */
.bottom-nav { display: none; }

/* ---- Page containers ---------------------------------------------------- */
.page { max-width: 640px; margin: var(--s-6) auto; padding: 0 var(--s-4); display: grid; gap: var(--s-5); }
.page-wide { max-width: 960px; margin: var(--s-5) auto; padding: 0 var(--s-4); }
.gallery-page { max-width: 1120px; margin: var(--s-4) auto; padding: 0 var(--s-3); }

/* ---- File browser ------------------------------------------------------- */
/* One segmented control, not three fat pills. Reads as a single element and
   shares the toolbar's button weight, so the view has one button language. */
.spaces {
  display: inline-flex; gap: 0; margin-bottom: var(--s-4);
  padding: 3px; background: var(--well);
  border: 1px solid var(--border); border-radius: var(--r-md);
}
.space-tab {
  height: var(--control-h); padding: 0 var(--s-4);
  font-size: var(--fs-sm); font-weight: 600; color: var(--muted);
  background: transparent; border: none; border-radius: calc(var(--r-md) - 3px);
  cursor: pointer; transition: color 0.12s ease, background 0.12s ease;
}
.space-tab:hover { color: var(--text); }
.space-tab.active {
  color: var(--text);
  background: var(--surface);
  box-shadow: 0 1px 3px rgba(9, 12, 18, 0.18), var(--edge);
}

/* The toolbar stays put while a long list scrolls under it. Back, the address
   and the clipboard buttons are exactly what you reach for part-way down a
   folder, and they were scrolling off the top of the screen.
   Sticky rather than fixed, so it still sits inside the content column and does
   not need its width calculating. */
.toolbar {
  position: sticky;
  top: var(--topbar-h);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-bottom: var(--s-3);
  /* Pull the background out to the column edges so rows do not show at the
     sides as they pass underneath. */
  margin-inline: calc(var(--s-3) * -1);
  padding: var(--s-2) var(--s-3);
  background: var(--surface);                    /* fallback: never transparent */
  border-bottom: 1px solid var(--border);
  border-radius: var(--r-md) var(--r-md) 0 0;
}
@supports (backdrop-filter: blur(1px)) {
  .toolbar {
    background: color-mix(in srgb, var(--surface) calc(var(--glass-alpha) * 100%), transparent);
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  }
}

/* The space tabs sit above it and scroll away normally; the selection bar sits
   below it and sticks too, since its actions apply to what you are scrolling.
   --toolbar-h is measured from the real toolbar at runtime (main.js): its
   height changes with density, coarse-pointer button sizes and two-row
   wrapping, and every hand-computed guess was wrong somewhere. The fallback
   only covers the moment before the script has measured. */
.selection-bar {
  position: sticky;
  top: calc(var(--topbar-h) + var(--toolbar-h, calc(var(--control-h) + var(--s-4))));
  z-index: 59;
}
.breadcrumb { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; font-size: var(--fs-base); color: var(--muted); }
.breadcrumb.small { font-size: var(--fs-sm); margin: var(--s-2) 0; }
.crumb { height: auto; padding: var(--s-1) var(--s-2); font-size: inherit; font-weight: 600; color: var(--accent); background: transparent; border: none; border-radius: var(--r-xs); cursor: pointer; }
.crumb:hover { background: var(--well); }

.listing {
  list-style: none; margin: 0; padding: 0;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-1); overflow: hidden;
}
.row-item { position: relative; display: flex; align-items: center; gap: var(--s-2); min-height: var(--row-h); padding: 0 var(--s-3) 0 var(--s-2); border-bottom: 1px solid var(--border); }
.row-item:last-child { border-bottom: none; }
@media (hover: hover) { .row-item:hover { background: var(--well); } }
.kebab { font-size: 1.25rem; line-height: 1; color: var(--muted); }
.row-menu { position: absolute; right: var(--s-3); top: calc(100% - 8px); min-width: 168px; z-index: 15; }

.entry {
  flex: 1; display: flex; align-items: center; gap: var(--s-3);
  min-width: 0; padding: 0 var(--s-2); align-self: stretch;
  font-size: var(--fs-base); color: var(--text);
  background: transparent; border: none; text-align: left; cursor: pointer;
}
.entry.static { cursor: default; }
.entry .icon {
  width: var(--tile); height: var(--tile); flex: 0 0 auto;
  display: grid; place-items: center;
  background: var(--well); border-radius: var(--r-sm); color: var(--muted);
}
.entry .icon svg { width: 20px; height: 20px; }
/* Folders read as the primary object; files sit quieter. */
.entry .icon.is-folder {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.entry .icon.is-file { color: var(--subtle); }
.entry-name { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.entry-meta { margin-left: auto; font-size: var(--fs-xs); color: var(--subtle); flex-shrink: 0; padding-left: var(--s-2); }
.entry-actions { display: flex; gap: var(--s-1); flex-shrink: 0; }

.empty { text-align: center; padding: var(--s-8); }

/* ---- Uploads ------------------------------------------------------------ */
/* Upload progress FLOATS over the page. It used to sit in the flow above the
   file list, so sending a folder of forty files shoved everything down the
   screen while you were still trying to use it. */
.uploads {
  position: fixed;
  right: var(--s-4);
  bottom: calc(var(--s-4) + env(safe-area-inset-bottom));
  z-index: 150;
  width: min(380px, calc(100vw - var(--s-6)));
  max-height: min(46vh, 420px);
  overflow-y: auto;
  padding: var(--s-3);
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
  display: grid;
  gap: var(--s-2);
}
.uploads-head {
  position: sticky; top: calc(var(--s-3) * -1);
  display: flex; align-items: center; gap: var(--s-2);
  margin: calc(var(--s-3) * -1) calc(var(--s-3) * -1) 0;
  padding: var(--s-3);
  background: var(--elevated);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  font-size: var(--fs-sm); font-weight: 600;
}
.uploads-head .spacer { flex: 1; }
.uploads-hide {
  border: none; background: transparent; color: var(--muted);
  font: inherit; font-size: var(--fs-xs); cursor: pointer; padding: 2px 6px; border-radius: var(--r-xs);
}
.uploads-hide:hover { background: var(--well); color: var(--text); }
body.uploads-collapsed .uploads { max-height: none; }

/* Reserve room underneath so the panel never sits on top of the last folders.
   Floating it was only half the fix: it stopped pushing the page down, but it
   still covered the rows at the bottom. */
body.has-uploads .page-wide,
body.has-uploads .content { padding-bottom: calc(46vh + var(--s-6)); }
body.has-uploads.uploads-collapsed .page-wide,
body.has-uploads.uploads-collapsed .content { padding-bottom: calc(var(--s-12) + var(--s-6)); }
body.uploads-collapsed .upload-row { display: none; }

/* On a phone it spans the width and sits above the bottom navigation. */
@media (max-width: 599px) {
  .uploads {
    left: var(--s-3); right: var(--s-3); width: auto;
    bottom: calc(var(--bottomnav-h) + env(safe-area-inset-bottom) + var(--s-3));
  }
}
.upload-row { display: flex; align-items: center; gap: var(--s-3); font-size: var(--fs-sm); }
.upload-name { flex: 0 0 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.upload-bar { flex: 1; height: 8px; background: var(--well); border-radius: var(--r-pill); overflow: hidden; }
.upload-fill { height: 100%; width: 0; background: var(--accent); border-radius: var(--r-pill); transition: width 0.2s ease; }
.upload-status { flex: 0 0 auto; min-width: 40px; text-align: right; color: var(--muted); }
.upload-status.failed { color: var(--danger); }

/* ---- Gallery ------------------------------------------------------------ */
.gallery-status { text-align: center; padding: var(--s-4); color: var(--muted); }
.month-header {
  position: sticky; top: var(--topbar-h); z-index: 1;
  font-size: var(--fs-md); font-weight: 600;
  margin: var(--s-5) 0 var(--s-3); padding: var(--s-2) var(--s-1);
  background: var(--bg); border-bottom: 1px solid var(--border);
}
.photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--s-1); }
.tile {
  position: relative; width: 100%; margin: 0; padding: 0;
  aspect-ratio: 1 / 1; border: none; border-radius: var(--r-sm);
  overflow: hidden; background: var(--well); cursor: pointer;
}
.tile img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.18s ease; }
@media (hover: hover) { .tile:hover img { transform: scale(1.05); } }
.tile:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent); }
.tile-pending { background: var(--well); }
.tile-video-ph::after, .tile-broken::after {
  content: '🎬'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 1.6rem; opacity: 0.5;
}
.tile-broken::after { content: '🖼️'; }
.video-badge { position: absolute; right: 6px; bottom: 6px; padding: 1px 7px; font-size: var(--fs-xs); font-weight: 600; color: #fff; background: rgba(0, 0, 0, 0.62); border-radius: var(--r-pill); }

/* Lightbox */
.lightbox { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; background: var(--scrim); }
.lightbox-stage { max-width: 92vw; max-height: 86vh; display: flex; align-items: center; justify-content: center; }
.lightbox-stage img, .lightbox-stage video { max-width: 92vw; max-height: 86vh; border-radius: var(--r-sm); box-shadow: var(--shadow-3); }
.lb-btn {
  position: absolute; display: grid; place-items: center;
  color: #fff; background: var(--lb-control); border: none; cursor: pointer; box-shadow: var(--shadow-3);
}
.lb-btn:hover { background: var(--lb-control-hover); }
.lb-close { top: 16px; right: 16px; width: 44px; height: 44px; border-radius: var(--r-pill); font-size: 1.6rem; }
.lb-nav { top: 50%; transform: translateY(-50%); width: 48px; height: 64px; border-radius: var(--r-md); font-size: 2rem; }
.lb-prev { left: 12px; } .lb-next { right: 12px; }
.lightbox-actions {
  position: absolute; bottom: calc(20px + env(safe-area-inset-bottom)); left: 50%; transform: translateX(-50%);
  display: flex; gap: var(--s-2); align-items: center;
  padding: var(--s-1); background: var(--lb-control); border-radius: var(--r-lg); box-shadow: var(--shadow-3);
}
.lightbox-actions .btn { color: #fff; }
.lightbox-actions .btn:hover { background: var(--lb-control-hover); }
.lightbox-toast {
  position: absolute; bottom: calc(84px + env(safe-area-inset-bottom)); left: 50%; transform: translateX(-50%);
  padding: var(--s-2) var(--s-4); border-radius: var(--r-md); font-size: var(--fs-sm);
  color: var(--text); background: var(--elevated); border: 1px solid var(--border); box-shadow: var(--shadow-3);
}
.lightbox-toast.error { color: #fff; background: var(--danger); border-color: var(--danger); }

/* ---- Dialogs ------------------------------------------------------------ */
dialog { border: none; border-radius: var(--r-lg); padding: 0; background: transparent; max-width: 460px; width: min(92vw, 460px); box-shadow: var(--shadow-3); }
dialog::backdrop { background: rgba(9, 12, 18, 0.5); }
.dialog-card { background: var(--elevated); border: 1px solid var(--border); border-radius: var(--r-lg); padding: var(--s-6); color: var(--text); }
.dialog-card h2 { font-size: var(--fs-xl); margin-bottom: var(--s-4); }
.dialog-card h3 { margin: var(--s-5) 0 var(--s-1); font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.dialog-card hr { border: none; border-top: 1px solid var(--border); margin: var(--s-5) 0; }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--s-2); margin-top: var(--s-5); }
.move-listing { max-height: 260px; overflow-y: auto; margin: var(--s-2) 0; }
.move-spaces { display: flex; gap: var(--s-2); margin-top: var(--s-2); }

/* ---- Admin / People ----------------------------------------------------- */
.status-line { color: var(--muted); }
.table-wrap { margin-top: var(--s-3); }
.admin-table { width: 100%; border-collapse: collapse; font-size: var(--fs-base); }
.admin-table th, .admin-table td { text-align: left; padding: var(--s-3); border-bottom: 1px solid var(--border); }
.admin-table th { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.04em; color: var(--subtle); font-weight: 600; }
.admin-actions { display: flex; gap: var(--s-1); flex-wrap: wrap; }
.badge { display: inline-flex; align-items: center; padding: 2px 8px; font-size: var(--fs-xs); font-weight: 600; border-radius: var(--r-pill); }
.badge-admin { color: var(--accent); background: var(--accent-weak); }
.badge-member { color: var(--muted); background: var(--well); }
.badge-disabled { color: var(--danger); background: var(--danger-weak); }
.quota { display: grid; gap: 4px; min-width: 120px; }
.quota-track { height: 6px; background: var(--well); border-radius: var(--r-pill); overflow: hidden; }
.quota-fill { height: 100%; background: var(--accent); border-radius: var(--r-pill); }
.quota-fill.warn { background: var(--warning); }
.quota-fill.full { background: var(--danger); }
.quota-text { font-size: var(--fs-xs); color: var(--subtle); }

/* ---- Alerts / messages / empty states ----------------------------------- */
.alert { display: flex; gap: var(--s-2); padding: var(--s-3) var(--s-4); border-radius: var(--r-md); font-size: var(--fs-sm); border: 1px solid; margin-top: var(--s-3); }
.alert.is-error, .error { color: var(--danger); background: var(--danger-weak); border-color: color-mix(in srgb, var(--danger) 30%, var(--surface)); border-radius: var(--r-md); padding: var(--s-3) var(--s-4); font-size: var(--fs-sm); margin-top: var(--s-3); border-width: 1px; border-style: solid; }
.success { color: var(--success); background: color-mix(in srgb, var(--success) 12%, var(--surface)); border: 1px solid color-mix(in srgb, var(--success) 30%, var(--surface)); border-radius: var(--r-md); padding: var(--s-3) var(--s-4); font-size: var(--fs-sm); margin-top: var(--s-3); }
.warn-banner { color: var(--warning); background: color-mix(in srgb, var(--warning) 14%, var(--surface)); border: 1px solid color-mix(in srgb, var(--warning) 32%, var(--surface)); border-radius: var(--r-md); padding: var(--s-3) var(--s-4); font-size: var(--fs-sm); margin-top: var(--s-3); }
.credential-value { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; background: var(--well); padding: 2px 8px; border-radius: var(--r-xs); }

.empty-state { display: grid; justify-items: center; gap: var(--s-3); text-align: center; padding: var(--s-12) var(--s-4); color: var(--muted); }
.empty-state .empty-icon { width: 64px; height: 64px; display: grid; place-items: center; background: var(--well); border-radius: var(--r-pill); color: var(--subtle); }
.empty-state .empty-icon svg { width: 30px; height: 30px; }
.empty-state h3 { font-size: var(--fs-md); color: var(--text); }

/* Toast host */
.toast-host { position: fixed; left: 50%; bottom: var(--s-6); transform: translateX(-50%); display: grid; gap: var(--s-2); z-index: 200; width: max-content; max-width: 92vw; }
.toast { padding: var(--s-3) var(--s-4); font-size: var(--fs-sm); color: var(--text); background: var(--elevated); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-3); }
.toast.is-error { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, var(--surface)); }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 899px) {
  .brand .wordmark { display: none; }
  .page-wide, .gallery-page, .page { padding-left: var(--s-3); padding-right: var(--s-3); }
}

@media (max-width: 599px) {
  :root { --topbar-h: 54px; }
  /* Primary nav moves to a bottom bar; keep only brand + title + avatar up top. */
  .topbar .nav { display: none; }
  .topbar .brand .wordmark { display: none; }
  .section-title { flex: 1; text-align: left; margin-left: var(--s-1); }

  .bottom-nav {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    display: flex; height: calc(var(--bottomnav-h) + env(safe-area-inset-bottom));
    padding-bottom: env(safe-area-inset-bottom);
    background: var(--surface); border-top: 1px solid var(--border); box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08);
  }
  .bottom-nav a {
    flex: 1; display: grid; place-items: center; gap: 2px;
    font-size: var(--fs-xs); font-weight: 600; color: var(--muted); text-decoration: none;
  }
  .bottom-nav a svg { width: 22px; height: 22px; }
  .bottom-nav a[aria-current="page"] { color: var(--accent); }
  body.has-bottom-nav .page,
  body.has-bottom-nav .page-wide,
  body.has-bottom-nav .gallery-page { padding-bottom: calc(var(--bottomnav-h) + env(safe-area-inset-bottom) + var(--s-4)); }
  .month-header { top: var(--topbar-h); }

  .card { padding: var(--s-4); border-radius: var(--r-md); }
  .photo-grid { grid-template-columns: repeat(3, 1fr); }

  /* Lightbox actions: full-width bottom bar */
  .lightbox-actions { left: 0; right: 0; bottom: 0; transform: none; width: 100%; border-radius: 0; justify-content: stretch; padding: var(--s-2) var(--s-2) calc(var(--s-2) + env(safe-area-inset-bottom)); }
  .lightbox-actions .btn { flex: 1; }
  .lightbox-toast { bottom: calc(72px + env(safe-area-inset-bottom)); }
  .lb-nav { width: 40px; height: 56px; }

  /* Dialogs become bottom sheets */
  dialog { width: 100vw; max-width: 100vw; margin: 0; margin-top: auto; margin-bottom: 0; }
  .dialog-card { border-radius: var(--r-lg) var(--r-lg) 0 0; padding: var(--s-5); max-height: 86vh; overflow: auto; }
  .dialog-actions { flex-direction: column-reverse; }
  .dialog-actions .btn { width: 100%; }

  /* Admin table -> stacked cards */
  .admin-table thead { display: none; }
  .admin-table, .admin-table tbody, .admin-table tr, .admin-table td { display: block; width: 100%; }
  .admin-table tr { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-1); padding: var(--s-3); margin-bottom: var(--s-3); }
  .admin-table td { display: flex; justify-content: space-between; align-items: center; gap: var(--s-3); padding: var(--s-1) 0; border: none; }
  .admin-table td::before { content: attr(data-label); font-size: var(--fs-xs); font-weight: 600; color: var(--subtle); text-transform: uppercase; letter-spacing: 0.04em; }
  .admin-table td.cell-actions { justify-content: flex-start; }
  .admin-table td.cell-actions::before { display: none; }
  .admin-actions { width: 100%; }
  .admin-actions .btn { flex: 1; }
}

/* ---- Install prompt ---------------------------------------------------- */
/* Sits above the mobile bottom nav (z-index 30) and clear of the home bar.  */
.install-banner {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom) + var(--s-4));
  z-index: 60;
  width: min(560px, calc(100vw - var(--s-6)));
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4);
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
}
.install-text { display: grid; gap: 2px; min-width: 0; }
.install-text strong { font-size: var(--fs-md); }
.install-text span { font-size: var(--fs-sm); color: var(--muted); }
.install-actions { display: flex; gap: var(--s-2); margin-left: auto; flex-shrink: 0; }

body.has-bottom-nav .install-banner {
  bottom: calc(var(--bottomnav-h) + env(safe-area-inset-bottom) + var(--s-3));
}

@media (max-width: 599px) {
  .install-banner { flex-direction: column; align-items: stretch; }
  .install-actions { margin-left: 0; }
  .install-actions .btn { flex: 1; }
}

/* ---- Drag-and-drop upload target --------------------------------------- */
.drop-hint {
  position: fixed;
  inset: var(--s-4);
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;             /* must not swallow the drop itself */
  font-size: var(--fs-lg);
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-weak);
  border: 2px dashed var(--accent);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
}

/* ---- Right-click menu --------------------------------------------------- */
.context-menu {
  position: fixed;
  z-index: 120;
  min-width: 180px;
  padding: var(--s-1);
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-3);
}

/* ---- File-manager chrome ------------------------------------------------ */
.nav-buttons { display: flex; gap: 2px; margin-right: var(--s-2); }
.nav-buttons .btn { font-size: var(--fs-lg); line-height: 1; }
.nav-buttons .btn:disabled { opacity: 0.35; cursor: default; }

.selection-bar {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-2) var(--s-3); margin-bottom: var(--s-3);
  background: var(--accent-weak);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: var(--r-md);
  font-size: var(--fs-sm); font-weight: 600; color: var(--accent);
}
.selection-hint { font-weight: 400; color: var(--muted); font-size: var(--fs-xs); }

.row-item.selected { background: var(--accent-weak); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
/* A cut item stays visible but reads as "going somewhere else". */
.row-item.cut-pending { opacity: 0.55; }

@media (max-width: 599px) {
  .selection-hint { display: none; }
}

/* ========================================================================
   Polish layer — frosted surfaces, depth, and finer motion.
   Blur is used only where a surface floats ABOVE content (sticky bar, menus,
   dialogs, overlays). Body text and large flat regions are never blurred, and
   every translucent surface declares an opaque fallback first so it stays
   legible where backdrop-filter is unsupported.
   ===================================================================== */

/* --- Floating chrome ---------------------------------------------------- */
.topbar {
  position: sticky;
  top: 0;
  background: var(--surface);                    /* fallback */
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--text) 4%, transparent);
}
@supports (backdrop-filter: blur(1px)) {
  .topbar {
    background: color-mix(in srgb, var(--surface) 72%, transparent);
    backdrop-filter: blur(18px) saturate(1.6);
    -webkit-backdrop-filter: blur(18px) saturate(1.6);
  }
}

.menu, .context-menu, .row-menu {
  background: var(--elevated);                   /* fallback */
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: 0 10px 30px -8px rgba(9, 12, 18, 0.35), 0 2px 8px -2px rgba(9, 12, 18, 0.2);
}
@supports (backdrop-filter: blur(1px)) {
  .menu, .context-menu, .row-menu {
    background: color-mix(in srgb, var(--elevated) 82%, transparent);
    backdrop-filter: blur(22px) saturate(1.7);
    -webkit-backdrop-filter: blur(22px) saturate(1.7);
  }
}

dialog::backdrop {
  background: color-mix(in srgb, #070a10 55%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.selection-bar {
  background: color-mix(in srgb, var(--accent) 10%, var(--surface));
}
@supports (backdrop-filter: blur(1px)) {
  .selection-bar {
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    backdrop-filter: blur(14px) saturate(1.4);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
  }
}

/* --- Rows: flat inside one rounded card, so corners never fight ---------- */
/* The container (.listing) is rounded and clips; rows are full-bleed with a
   hairline divider. Hover and selection are full-width tints, never their own
   rounded rectangle — that mismatch was the "uneven corners" look. */
.row-item {
  position: relative;
  transition: background-color 110ms ease;
}
.row-item:hover { background: color-mix(in srgb, var(--text) 4%, transparent); }
.row-item.selected { background: color-mix(in srgb, var(--accent) 13%, transparent); }
.row-item.selected:hover { background: color-mix(in srgb, var(--accent) 17%, transparent); }
/* A lit left edge, full row height, marks the selection cleanly. */
.row-item.selected::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--accent);
}
.entry-name { border-radius: 4px; padding: 1px 4px; margin: -1px -4px; }
.row-item.selected .entry-name:hover {
  background: color-mix(in srgb, var(--text) 8%, transparent);
  cursor: text;                                   /* hints click-to-rename */
}

/* --- Rename in place ---------------------------------------------------- */
.rename-input {
  flex: 1; min-width: 0;
  font: inherit; color: var(--text);
  background: var(--elevated);
  border: 1px solid var(--accent);
  border-radius: var(--r-sm);
  padding: 2px 6px;
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* --- Toolbar grouping --------------------------------------------------- */
.tool-group { display: flex; gap: var(--s-2); align-items: center; }
.tool-group + .tool-group {
  margin-left: var(--s-3);
  padding-left: var(--s-3);
  border-left: 1px solid var(--border);
}
.tool-group .btn:disabled { opacity: 0.4; cursor: default; }
.btn.is-danger { color: var(--danger); }

@media (max-width: 799px) {
  .toolbar { flex-wrap: wrap; row-gap: var(--s-2); }
  .tool-group + .tool-group { margin-left: 0; padding-left: 0; border-left: none; }
}

/* Touch targets: 32px is fine for a mouse and fiddly for a thumb. */
@media (pointer: coarse) {
  .tool-group .btn, .nav-buttons .btn { min-height: 40px; padding-inline: var(--s-3); }
  .row-item { padding-block: var(--s-1); }
  .entry { padding-block: var(--s-3); }
}

/* --- Dragging items to move them ---------------------------------------- */
.row-item[draggable="true"] { cursor: grab; }
.row-item.dragging { opacity: 0.45; cursor: grabbing; }

/* Anything accepting the drop lights up: folder rows, breadcrumbs, space tabs. */
.drop-target {
  background: color-mix(in srgb, var(--accent) 18%, transparent) !important;
  box-shadow: inset 0 0 0 2px var(--accent) !important;
  border-radius: var(--r-md);
}

/* ---- Sidebar folder tree ------------------------------------------------ */
.layout { display: grid; grid-template-columns: 264px minmax(0, 1fr); gap: var(--s-5); align-items: start; }
/* Collapsed removes the pane from the DOM flow, so the grid must drop to ONE
   column. Leaving a 0-width first column here put the file list in it and made
   everything vanish. */
body.sidebar-collapsed .layout { grid-template-columns: minmax(0, 1fr); gap: 0; }

.sidebar {
  position: sticky;
  top: calc(var(--topbar-h) + var(--s-4));
  max-height: calc(100vh - var(--topbar-h) - var(--s-6));
  overflow: auto;
  padding: var(--s-3);
  background: var(--surface);                       /* fallback */
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
}
@supports (backdrop-filter: blur(1px)) {
  .sidebar {
    background: color-mix(in srgb, var(--surface) 76%, transparent);
    backdrop-filter: blur(16px) saturate(1.5);
    -webkit-backdrop-filter: blur(16px) saturate(1.5);
  }
}
/* Collapsed: the pane simply vanishes and the list takes its place. The toggle
   lives permanently in the toolbar, so nothing ever floats over content. */
body.sidebar-collapsed .sidebar { display: none; }
#sidebar-toggle.active { color: var(--accent); }

.sidebar-head { display: flex; align-items: center; margin-bottom: var(--s-2); }
.sidebar-title {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--subtle);
}

.tree { display: grid; gap: 1px; }
.tree-row { display: flex; align-items: center; gap: 2px; border-radius: var(--r-sm); }
.tree-row:hover { background: color-mix(in srgb, var(--text) 5%, transparent); }
.tree-twisty {
  flex-shrink: 0; width: 20px; height: 26px; padding: 0;
  display: grid; place-items: center;
  background: none; border: none; cursor: pointer; color: var(--subtle);
}
.tree-twisty svg { width: 13px; height: 13px; transition: transform 0.12s ease; }
.tree-twisty.open svg { transform: rotate(90deg); }
.tree-twisty:hover { color: var(--text); }
.tree-label {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--s-2);
  padding: 5px var(--s-2); background: none; border: none; cursor: pointer;
  font-size: var(--fs-sm); color: var(--text); text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tree-icon { flex-shrink: 0; font-size: 13px; }
.tree-children { padding-left: 14px; border-left: 1px solid var(--border); margin-left: 9px; }
.tree-empty { padding: 4px var(--s-3); font-size: var(--fs-xs); color: var(--subtle); }

.tree-node.active > .tree-row,
.tree-trash.active {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent);
}
.tree-node.active > .tree-row .tree-label,
.tree-trash.active .tree-label { color: var(--accent); font-weight: 600; }

/* On a phone the pane becomes a slide-over drawer rather than a column, so the
   folder tree is still reachable. The hamburger opens and closes it. */
@media (max-width: 899px) {
  .layout { grid-template-columns: minmax(0, 1fr); }
  .sidebar {
    display: block;
    position: fixed;
    left: 0; top: var(--topbar-h); bottom: 0;
    width: min(300px, 82vw);
    z-index: 80;
    margin: 0;
    max-height: none;
    border-radius: 0;
    border-width: 0 1px 0 0;
    transform: translateX(-101%);
    transition: transform 0.2s ease;
  }
  body.drawer-open .sidebar { transform: none; }
  /* Tapping the dimmed area closes the drawer. */
  body.drawer-open::after {
    content: "";
    position: fixed; inset: var(--topbar-h) 0 0 0; z-index: 79;
    background: var(--scrim);
  }
  /* Collapsed is a desktop-only idea; on a phone the drawer state rules. */
  body.sidebar-collapsed .sidebar { display: block; }
}

/* A file manager should use the screen it is given. 960px was right for a
   single column; with the folder pane beside it, the list needs the room. */
@media (min-width: 900px) {
  #browser.page-wide { max-width: min(1440px, 100% - var(--s-6)); }
}

/* ---- Appearance settings ------------------------------------------------ */
.setting { border: none; margin: 0 0 var(--s-5); padding: 0; }
.setting legend {
  padding: 0; margin-bottom: var(--s-2);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--subtle);
}
.choices { display: flex; flex-wrap: wrap; gap: var(--s-2); }
/* The radio itself is the state; the label is the visible control. */
.choices input { position: absolute; opacity: 0; pointer-events: none; }
.choice {
  display: inline-flex; align-items: center; gap: var(--s-2);
  height: var(--control-h); padding: 0 var(--s-3);
  font-size: var(--fs-sm); font-weight: 500; color: var(--muted);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-sm); cursor: pointer;
  transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.choice:hover { color: var(--text); border-color: var(--border-strong); }
.choices input:checked + .choice {
  color: var(--accent); border-color: var(--accent); background: var(--accent-weak);
}
.choices input:focus-visible + .choice { box-shadow: var(--ring); }
.swatch { width: 12px; height: 12px; border-radius: 50%; background: hsl(var(--hue-blue) 78% 55%); }
.swatch[data-accent="indigo"] { background: hsl(var(--hue-indigo) 78% 60%); }
.swatch[data-accent="teal"]   { background: hsl(var(--hue-teal) 58% 45%); }
.swatch[data-accent="violet"] { background: hsl(var(--hue-violet) 62% 60%); }
.swatch[data-accent="amber"]  { background: hsl(var(--hue-amber) 80% 50%); }
.swatch[data-accent="rose"]   { background: hsl(var(--hue-rose) 70% 55%); }

/* ---- Storage allocation (in Appearance, admins only) -------------------- */
.setting-heading {
  margin: var(--s-5) 0 var(--s-3);
  padding-top: var(--s-4);
  border-top: 1px solid var(--border);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--subtle);
}
.quota-row { display: grid; gap: var(--s-2); margin-bottom: var(--s-4); }
.quota-who { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); font-size: var(--fs-sm); }
.quota-who span { color: var(--subtle); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.quota-controls { display: flex; align-items: center; gap: var(--s-2); }
.quota-slider { flex: 1; min-width: 0; accent-color: var(--accent); }
.quota-readout {
  font-size: var(--fs-sm); color: var(--muted); font-variant-numeric: tabular-nums;
  min-width: 112px; text-align: right;
}
.quota-summary { margin: 0 0 var(--s-3); font-size: var(--fs-sm); color: var(--muted); }
.quota-summary.over { color: var(--warning); }

/* Copyable setup commands */
.command-row { display: flex; align-items: center; gap: var(--s-3); margin-bottom: var(--s-3); flex-wrap: wrap; }
.command-meta { display: grid; min-width: 96px; }
.command-meta strong { font-size: var(--fs-sm); }
.command-meta span { font-size: var(--fs-xs); color: var(--subtle); }
.command-text {
  flex: 1; min-width: 180px; overflow-x: auto; white-space: nowrap;
  padding: var(--s-2) var(--s-3);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--fs-xs); color: var(--text);
  background: var(--well); border: 1px solid var(--border); border-radius: var(--r-sm);
}

/* ---- Your own space, in the top bar ------------------------------------- */
.capacity {
  display: flex; align-items: center; gap: var(--s-2);
  height: var(--control-h); padding: 0 var(--s-3); margin-right: var(--s-2);
  background: transparent; border: 1px solid var(--border);
  border-radius: var(--r-pill); cursor: pointer;
  font-size: var(--fs-xs); color: var(--muted);
}
.capacity:hover { border-color: var(--border-strong); color: var(--text); }
.capacity-track { width: 56px; height: 5px; border-radius: 999px; background: var(--well); overflow: hidden; }
.capacity-fill { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.capacity-fill.warn { background: var(--warning); }
.capacity-fill.full { background: var(--danger); }
.capacity-text { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- Storage dashboard (People page) ------------------------------------ */
.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: var(--s-3); margin-bottom: var(--s-4); }
.stat { display: grid; gap: 2px; }
.stat strong { font-size: var(--fs-lg); font-weight: 600; font-variant-numeric: tabular-nums; }
.stat span { font-size: var(--fs-xs); color: var(--subtle); text-transform: uppercase; letter-spacing: 0.05em; }

.stack-bar {
  display: flex; height: 12px; border-radius: 999px; overflow: hidden;
  background: var(--well); margin-bottom: var(--s-3);
}
.stack-seg { display: block; height: 100%; }
.stack-seg[data-tone="0"] { background: var(--accent); }
.stack-seg[data-tone="1"] { background: color-mix(in srgb, var(--accent) 70%, var(--surface)); }
.stack-seg[data-tone="2"] { background: var(--success); }
.stack-seg[data-tone="3"] { background: var(--warning); }
.stack-seg[data-tone="4"] { background: color-mix(in srgb, var(--accent) 40%, var(--danger)); }
.stack-seg[data-tone="other"] { background: var(--border-strong); }
.stack-seg[data-tone="free"] { background: transparent; }

.stack-legend { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-bottom: var(--s-3); font-size: var(--fs-xs); color: var(--muted); }
.legend-item { display: inline-flex; align-items: center; gap: var(--s-2); }
.legend-item i { width: 9px; height: 9px; border-radius: 2px; }
.legend-item i[data-tone="0"] { background: var(--accent); }
.legend-item i[data-tone="1"] { background: color-mix(in srgb, var(--accent) 70%, var(--surface)); }
.legend-item i[data-tone="2"] { background: var(--success); }
.legend-item i[data-tone="3"] { background: var(--warning); }
.legend-item i[data-tone="4"] { background: color-mix(in srgb, var(--accent) 40%, var(--danger)); }
.legend-item i[data-tone="other"] { background: var(--border-strong); }
.legend-item i[data-tone="free"] { background: var(--well); border: 1px solid var(--border); }

/* The kebab now opens the shared floating menu, so no clipping is possible. */
.kebab svg { width: 16px; height: 16px; }
.build-stamp {
  margin: var(--s-4) 0 0; padding-top: var(--s-3);
  border-top: 1px solid var(--border);
  font-size: var(--fs-xs); color: var(--subtle); font-variant-numeric: tabular-nums;
}

/* Depth applies to the panels people actually look at, so the setting is
   visible in dark mode where a shadow alone is not. */
.listing, .card, .sidebar, .menu, .context-menu, .dialog-card, .selection-bar {
  border-color: var(--border-lifted);
}
.listing, .card, .sidebar { background: var(--surface-lift); }
:root[data-depth="raised"] .listing,
:root[data-depth="raised"] .card,
:root[data-depth="raised"] .sidebar { box-shadow: var(--shadow-2); }
:root[data-depth="flat"] .listing,
:root[data-depth="flat"] .card,
:root[data-depth="flat"] .sidebar,
:root[data-depth="flat"] .menu,
:root[data-depth="flat"] .context-menu,
:root[data-depth="flat"] .dialog-card { box-shadow: none; }

.setting-heading.first { margin-top: var(--s-4); padding-top: 0; border-top: none; }

/* ---- Selecting without opening ------------------------------------------ */
/* A checkbox per row: shown on hover with a mouse, and always once anything is
   selected. A touchscreen has no hover, so it also appears whenever selecting. */
.row-pick {
  flex: 0 0 auto;
  width: 17px; height: 17px;
  margin-left: var(--s-2);
  accent-color: var(--accent);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s ease;
}
.row-item:hover .row-pick,
.row-pick:focus-visible,
.row-item.selected .row-pick,
body.picking .row-pick { opacity: 1; }

/* With no hover to reveal it, the checkbox is always there on touch. */
@media (pointer: coarse) {
  .row-pick { opacity: 1; }
}

/* ==========================================================================
   Glass
   Two ingredients, and both are needed. The AMBIENT layer paints soft pools of
   accent colour behind everything; the GLASS surfaces then blur and saturate
   whatever sits behind them. Without the ambient layer, blurring a flat
   background just produces the same flat background and the effect is wasted.
   Every glass surface declares a solid colour first, so a browser without
   backdrop-filter — or the "off" setting — still gets a proper opaque panel.
   ========================================================================== */

body::before {
  content: "";
  position: fixed;
  inset: -20vmax;
  z-index: -1;
  pointer-events: none;
  opacity: var(--ambient);
  transition: opacity 0.3s ease;
  background:
    radial-gradient(38vmax 38vmax at 12% -8%,  hsl(var(--h) var(--sat) 55% / 0.20), transparent 60%),
    radial-gradient(32vmax 32vmax at 96% 12%,  hsl(calc(var(--h) + 40) var(--sat) 55% / 0.16), transparent 60%),
    radial-gradient(42vmax 42vmax at 55% 108%, hsl(calc(var(--h) - 35) var(--sat) 55% / 0.14), transparent 62%);
}

/* Surfaces that float above content take the glass treatment. Content surfaces
   (the file rows themselves) deliberately do not — blurring behind text you are
   reading is where glass stops looking expensive and starts looking cheap. */
@supports (backdrop-filter: blur(1px)) {
  .topbar,
  .sidebar,
  .menu,
  .context-menu,
  .dialog-card,
  .selection-bar,
  .listing,
  .card {
    background: color-mix(in srgb, var(--surface) calc(var(--glass-alpha) * 100%), transparent);
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  }

  /* The lit top edge is what suggests a pane has thickness. */
  .topbar, .sidebar, .menu, .context-menu, .dialog-card, .listing, .card {
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, var(--glass-edge)),
      var(--shadow-2);
  }

  .listing { border: 1px solid color-mix(in srgb, var(--text) 8%, transparent); }
}

/* Rows stay legible: no blur under text, just a subtle tint on hover. */
.row-item { backdrop-filter: none; }

dialog::backdrop {
  background: color-mix(in srgb, #05070c 45%, transparent);
  backdrop-filter: blur(calc(var(--glass-blur) * 0.4)) saturate(1.2);
  -webkit-backdrop-filter: blur(calc(var(--glass-blur) * 0.4)) saturate(1.2);
}

/* ---- Settings, grouped -------------------------------------------------- */
.settings-tabs {
  display: flex;
  gap: 2px;
  padding: 3px;
  margin: var(--s-4) 0 var(--s-5);
  background: color-mix(in srgb, var(--text) 6%, transparent);
  border-radius: var(--r-md);
}
.settings-tab {
  flex: 1;
  height: var(--control-h);
  padding: 0 var(--s-2);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--muted);
  background: transparent;
  border: none;
  border-radius: calc(var(--r-md) - 3px);
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}
.settings-tab:hover { color: var(--text); }
.settings-tab.active {
  color: var(--text);
  background: var(--surface);
  box-shadow: var(--shadow-1);
}
.settings-panel { display: grid; }
#settings-dialog .dialog-card { width: min(94vw, 520px); }

/* A photo's own thumbnail in place of the generic file icon. */
.icon.is-thumb { padding: 0; overflow: hidden; background: var(--well); }
.icon.is-thumb img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  /* Fade in, so a slow thumbnail does not flash an empty box. */
  animation: thumb-in 0.18s ease both;
}
@keyframes thumb-in { from { opacity: 0; } to { opacity: 1; } }

/* The panel stays up when something failed, so it needs room for the message
   and the retry button. Never auto-hidden in that state. */
.uploads-foot { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2); padding: var(--s-2) var(--s-3); border-top: 1px solid var(--border); font-size: var(--fs-sm); color: var(--muted); }
.uploads-foot span { flex: 1 1 12rem; }
.uploads-head .failed { color: var(--danger); font-weight: 600; }

/* The settings dialog on short windows: the card overflowed the dialog with
   the Done row pushed past the viewport (reported on the desktop, 08-15).
   The card becomes a column whose PANELS scroll; the tab strip and the
   actions row always stay on screen. */
#settings-dialog[open] { display: flex; overflow: hidden; max-height: calc(100dvh - 40px); }
#settings-dialog .dialog-card { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
#settings-dialog .settings-panel:not([hidden]) { display: block; overflow-y: auto; min-height: 0; }
#settings-dialog .settings-tabs, #settings-dialog .dialog-actions, #settings-dialog h2 { flex-shrink: 0; }
