/* ============================================================
   MoveMyWork — custom styles layered over Bootstrap 5.
   Aesthetic: modern, minimal. Cool whites, inked type, one accent.
   Tokens align with workrooms.css so the whole app feels like
   one product. (Marketing homepage keeps its own warmer,
   Fraunces-driven look via marketing.css.)
   ============================================================ */

:root {
  /* v10.71.7: explicit light color-scheme so the browser doesn't
     fall back to user OS preference for UA chrome (date picker
     icons, scrollbars). [data-theme="dark"] sets it to 'dark'. */
  color-scheme: light;

  --mmw-ink:        #14171a;   /* near-black, very slightly cool */
  --mmw-ink-soft:   #4b5055;
  --mmw-muted:      #6b7177;
  --mmw-paper:      #fafbfc;   /* cool near-white page background */
  --mmw-card:       #ffffff;
  --mmw-line:       #e4e6e9;   /* neutral grey border */
  --mmw-line-soft:  #f1f3f4;   /* lighter hover / subtle fills */
  --mmw-accent:     #c4502b;   /* terracotta — one accent, the brand */
  --mmw-accent-ink: #8a3519;
  --mmw-ok:         #2f6b3a;
  --mmw-danger:     #dc3545;   /* matches workrooms.css alerts */

  /* Nav bar gets its own warm-ivory tint so the header across
     every app page contrasts nicely with the cool body below —
     a deliberate bit of brand character. Changing --mmw-paper
     (page background) no longer drags the nav along. */
  --mmw-nav-bg:     #f6f2ea;
  --mmw-nav-line:   #e7e1d4;

  --mmw-radius:     12px;
  --mmw-radius-lg:  16px;
  --mmw-shadow:     0 1px 0 rgba(21,24,28,.04), 0 10px 30px -18px rgba(21,24,28,.18);

  /* --mmw-serif kept for back-compat — still usable if someone
     wants editorial emphasis somewhere — but no longer applied to
     h1-h3 by default. Fraunces isn't explicitly loaded on app
     pages, so previously most users saw Georgia anyway. */
  --mmw-serif:  'Fraunces', 'Source Serif 4', Georgia, 'Times New Roman', serif;
  --mmw-sans:   'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mmw-mono:   'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}

/* ============================================================
   Dark mode tokens. v10.71.

   Activated by setting `data-theme="dark"` on <html> (done by an
   inline early-paint script that reads localStorage, plus a Settings
   toggle that writes localStorage and updates the attribute live).

   Tokens are deliberately conservative — this is "version 1" dark
   mode and may have a few rough spots in component-specific
   hardcoded colors (alerts, badges, certain inline styles). We
   polish those as we spot them rather than trying to perfect
   every component up front.

   Design intent: a warm-leaning charcoal rather than pure black,
   to echo the marketing site's deep-paper-on-ink vibe without
   being totally cold. The accent terracotta stays the same; it
   works on both light and dark.
   ============================================================ */
[data-theme="dark"] {
  /* v10.71.7: tell the browser this subtree uses dark UA chrome.
     Native controls — date/time picker indicators, scrollbars,
     form-control borders on focus — pick their dark-appropriate
     defaults from this. Without it Safari renders the calendar
     and clock icons in their light-mode dark-grey, making them
     near-invisible on a dark input background. */
  color-scheme: dark;

  --mmw-ink:        #ece8df;   /* warm near-white for body text */
  --mmw-ink-soft:   #b4afa4;
  --mmw-muted:      #8b8678;
  --mmw-paper:      #15171a;   /* warm-cool charcoal page background */
  --mmw-card:       #1d1f23;   /* surfaces sit slightly above the page */
  --mmw-line:       #2c2f34;
  --mmw-line-soft:  #24262a;
  --mmw-accent:     #d96638;   /* slightly brighter terracotta for
                                  dark — pops without being neon */
  --mmw-accent-ink: #f0a37c;   /* lighter ink shade for use against
                                  dark backgrounds where the original
                                  --mmw-accent-ink would be too dim */
  --mmw-ok:         #6fb37e;
  --mmw-danger:     #f06a73;

  /* Nav stays a touch lighter than the page to maintain the
     "header lifts off the canvas" feel from light mode. */
  --mmw-nav-bg:     #1f2126;
  --mmw-nav-line:   #2c2f34;

  --mmw-shadow:     0 1px 0 rgba(0,0,0,.4), 0 10px 30px -18px rgba(0,0,0,.6);
}

/* Smooth the transition when the user toggles modes. Apply just
   to colors/backgrounds — animating box-shadow or border-radius
   would create visible glitches. */
body, .mmw-card, .mmw-nav, .mmw-clip, .mmw-textarea, .mmw-drop,
.btn, input, textarea, select {
  transition: background-color 0.18s ease, color 0.18s ease,
              border-color 0.18s ease;
}

/* ============================================================
   Dark-mode overrides for Bootstrap utilities and components.

   v10.71 shipped dark mode with token overrides for our own
   --mmw-* variables, which covered most surfaces. But many pages
   use Bootstrap's utility classes (.text-muted, .alert-*,
   .btn-outline-secondary, .form-control, .form-select, etc.)
   whose colors are baked into Bootstrap's compiled CSS — those
   stay light-mode-colored and become invisible or low-contrast
   against dark backgrounds.

   Rather than rebuild Bootstrap with custom SASS variables, we
   override the specific utilities our app actually uses. Audited
   from the codebase: text-muted (82×), btn-outline-secondary (26×),
   alert-* (~20×), form-control/select, border-bottom utilities.
   ============================================================ */
[data-theme="dark"] {
  /* The most-used utility — small grey text on every settings
     page, dashboard, files list, etc. Without this override it
     uses Bootstrap's #6c757d which is invisible on dark cards. */
  --bs-secondary-color: var(--mmw-muted);
  --bs-tertiary-color:  var(--mmw-ink-soft);
}
[data-theme="dark"] .text-muted {
  color: var(--mmw-muted) !important;
}
[data-theme="dark"] .text-secondary {
  color: var(--mmw-ink-soft) !important;
}
[data-theme="dark"] .text-warning {
  color: #f5b765 !important;
}
[data-theme="dark"] .text-danger {
  color: var(--mmw-danger) !important;
}

/* Outlined buttons — Bootstrap's default uses hardcoded #6c757d
   border + dark text, which is wrong on dark backgrounds. Make
   them readable. */
[data-theme="dark"] .btn-outline-secondary {
  color: var(--mmw-ink);
  border-color: var(--mmw-line);
}
[data-theme="dark"] .btn-outline-secondary:hover {
  background: var(--mmw-line-soft);
  color: var(--mmw-ink);
  border-color: var(--mmw-muted);
}
[data-theme="dark"] .btn-outline-primary {
  color: var(--mmw-accent);
  border-color: var(--mmw-accent);
}
[data-theme="dark"] .btn-outline-primary:hover {
  background: var(--mmw-accent);
  color: #fff;
}
[data-theme="dark"] .btn-outline-danger {
  color: var(--mmw-danger);
  border-color: var(--mmw-danger);
}
[data-theme="dark"] .btn-outline-danger:hover {
  background: var(--mmw-danger);
  color: #fff;
}
/* Solid buttons */
[data-theme="dark"] .btn-primary {
  background: var(--mmw-accent);
  border-color: var(--mmw-accent);
  color: #fff;
}
[data-theme="dark"] .btn-primary:hover,
[data-theme="dark"] .btn-primary:focus {
  background: var(--mmw-accent-ink);
  border-color: var(--mmw-accent-ink);
  color: #fff;
}
[data-theme="dark"] .btn-secondary {
  background: var(--mmw-line);
  border-color: var(--mmw-line);
  color: var(--mmw-ink);
}
[data-theme="dark"] .btn-secondary:hover {
  background: var(--mmw-ink-soft);
  border-color: var(--mmw-ink-soft);
}

/* Form controls — by far the most jarring thing if left light.
   form-control, form-select, form-check-input all need overrides. */
[data-theme="dark"] .form-control,
[data-theme="dark"] .form-select,
[data-theme="dark"] .form-check-input,
[data-theme="dark"] textarea,
[data-theme="dark"] input[type="text"],
[data-theme="dark"] input[type="email"],
[data-theme="dark"] input[type="password"],
[data-theme="dark"] input[type="url"],
[data-theme="dark"] input[type="number"] {
  background-color: var(--mmw-paper);
  border-color: var(--mmw-line);
  color: var(--mmw-ink);
}
[data-theme="dark"] .form-control:focus,
[data-theme="dark"] .form-select:focus,
[data-theme="dark"] textarea:focus,
[data-theme="dark"] input:focus {
  background-color: var(--mmw-paper);
  border-color: var(--mmw-accent);
  color: var(--mmw-ink);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mmw-accent) 25%, transparent);
}
[data-theme="dark"] .form-control::placeholder,
[data-theme="dark"] textarea::placeholder,
[data-theme="dark"] input::placeholder {
  color: var(--mmw-muted);
  opacity: 0.7;
}
[data-theme="dark"] .form-label {
  color: var(--mmw-ink);
}
[data-theme="dark"] .form-text {
  color: var(--mmw-muted);
}
[data-theme="dark"] .form-control-plaintext {
  color: var(--mmw-ink);
}
[data-theme="dark"] .input-group-text {
  background: var(--mmw-line-soft);
  border-color: var(--mmw-line);
  color: var(--mmw-ink);
}

/* v10.71.9: paint our own calendar and clock icons on date/time
   inputs so both browsers (Safari, Chrome, Firefox) and both
   themes get a consistent, themed picker indicator.

   Background: across the v10.71.7 → .8 attempts I tried two
   approaches that didn't work:

     - v10.71.7 set `color-scheme: dark` and tried to invert the
       native indicator with `filter: invert(0.9)`. Worked on
       date inputs in some Safari builds but broke them in
       others; time inputs got no icon at all because Safari
       doesn't render one for type=time.

     - v10.71.8 painted a clock icon for type=time only, leaving
       the date indicator to the previous filter — but the filter
       made the (already-light) calendar icon dark again, hiding
       it.

   The honest solution: paint BOTH icons ourselves. Same pattern
   for both — background-image with an inline SVG data URI,
   light and dark variants because currentColor doesn't resolve
   inside data URIs. Suppress the native picker indicator with
   opacity:0 so it doesn't double up on browsers that DO draw
   one. The native click target stays, so tapping the painted
   icon still opens the native picker.

   `color-scheme: dark` from v10.71.7 stays in :root and dark
   block — it's still useful for scrollbars and form-control
   focus rings — but we no longer rely on it for the picker
   indicator. */

/* Common — applies to both date and time inputs */
input[type="date"],
input[type="time"],
input[type="datetime-local"] {
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 16px 16px;
  /* padding-right reserves space for our painted icon so the
     typed digits don't slide under it. */
  padding-right: 34px;
}

/* Light-mode icons — stroked in --mmw-muted (#6b7177) */
input[type="date"] {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236b7177' stroke-width='1.5'><rect x='2' y='3.5' width='12' height='11' rx='1'/><path d='M2 6.5h12M5 2v3M11 2v3' stroke-linecap='round'/></svg>");
}
input[type="time"] {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236b7177' stroke-width='1.5'><circle cx='8' cy='8' r='6.25'/><path d='M8 4.5v3.7l2.2 1.3' stroke-linecap='round'/></svg>");
}

/* Dark-mode icons — same SVGs, stroke swapped to --mmw-ink-soft (#b4afa4) */
[data-theme="dark"] input[type="date"] {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23b4afa4' stroke-width='1.5'><rect x='2' y='3.5' width='12' height='11' rx='1'/><path d='M2 6.5h12M5 2v3M11 2v3' stroke-linecap='round'/></svg>");
}
[data-theme="dark"] input[type="time"] {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23b4afa4' stroke-width='1.5'><circle cx='8' cy='8' r='6.25'/><path d='M8 4.5v3.7l2.2 1.3' stroke-linecap='round'/></svg>");
}

/* Suppress the browser's own picker indicator. We paint our own
   above so we don't want a second icon stacking next to it on
   Chrome (where it's drawn) and Firefox (where it's also drawn).
   opacity:0 keeps it click-targetable so tapping where the
   painted icon shows still opens the native picker.

   The width override sizes the invisible hit area to match our
   painted icon position, so the click target overlaps it
   correctly. */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
  opacity: 0;
  width: 24px;
  cursor: pointer;
  margin-right: -4px;
}

/* Alerts — used for flash messages (account share, error states).
   Bootstrap's pastels are nearly invisible on dark. Use stronger
   tinted backgrounds with bright text. */
[data-theme="dark"] .alert-success {
  background: color-mix(in srgb, var(--mmw-ok) 18%, var(--mmw-card));
  border-color: color-mix(in srgb, var(--mmw-ok) 40%, var(--mmw-card));
  color: #a8e0b3;
}
[data-theme="dark"] .alert-warning {
  background: color-mix(in srgb, #f5b765 18%, var(--mmw-card));
  border-color: color-mix(in srgb, #f5b765 40%, var(--mmw-card));
  color: #f5b765;
}
[data-theme="dark"] .alert-danger {
  background: color-mix(in srgb, var(--mmw-danger) 18%, var(--mmw-card));
  border-color: color-mix(in srgb, var(--mmw-danger) 40%, var(--mmw-card));
  color: #f7b0b5;
}
[data-theme="dark"] .alert-info {
  background: color-mix(in srgb, #5bc0de 18%, var(--mmw-card));
  border-color: color-mix(in srgb, #5bc0de 40%, var(--mmw-card));
  color: #b8e3ef;
}

/* Badges — used inline on file rows, calendar feeds, etc. */
[data-theme="dark"] .badge.bg-secondary {
  background-color: var(--mmw-line) !important;
  color: var(--mmw-ink);
}
[data-theme="dark"] .badge.bg-info {
  background-color: #4a98b5 !important;
}

/* Bootstrap dividers + borders */
[data-theme="dark"] .border-bottom,
[data-theme="dark"] .border-top,
[data-theme="dark"] .border {
  border-color: var(--mmw-line) !important;
}

/* List items with border-bottom utility on files page, etc. */
[data-theme="dark"] .border-bottom {
  border-bottom-color: var(--mmw-line) !important;
}

/* Anchor (link) default — Bootstrap's blue is fine on white but
   loud on dark. Use the accent terracotta for hyperlinks. */
[data-theme="dark"] a {
  color: var(--mmw-accent);
}
[data-theme="dark"] a:hover {
  color: var(--mmw-accent-ink);
}
/* But don't repaint links inside buttons (they inherit button color) */
[data-theme="dark"] .btn a,
[data-theme="dark"] a.btn {
  color: inherit;
}

/* Bootstrap dropdown (rare in app, but present in some places) */
[data-theme="dark"] .dropdown-menu {
  background: var(--mmw-card);
  border-color: var(--mmw-line);
}
[data-theme="dark"] .dropdown-item {
  color: var(--mmw-ink);
}
[data-theme="dark"] .dropdown-item:hover {
  background: var(--mmw-line-soft);
  color: var(--mmw-ink);
}

/* Tables (used in some admin/analytics places — defensive) */
[data-theme="dark"] table,
[data-theme="dark"] .table {
  color: var(--mmw-ink);
  border-color: var(--mmw-line);
}
[data-theme="dark"] .table > :not(caption) > * > * {
  background-color: transparent;
  color: var(--mmw-ink);
  border-bottom-color: var(--mmw-line);
}

/* Code blocks / inline code */
[data-theme="dark"] code,
[data-theme="dark"] pre {
  background: var(--mmw-line-soft);
  color: var(--mmw-ink);
  border-color: var(--mmw-line);
}

/* Bootstrap btn-link (used by "browse" in dashboard upload zone) */
[data-theme="dark"] .btn-link {
  color: var(--mmw-accent);
}
[data-theme="dark"] .btn-link:hover {
  color: var(--mmw-accent-ink);
}

/* Bootstrap overrides ---------------------------------------- */
body {
  background: var(--mmw-paper);
  color: var(--mmw-ink);
  font-family: var(--mmw-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* Sticky-footer layout: on logged-in app pages, make the body a
   flex column so the footer pins to the bottom of the viewport
   when content is short, while still flowing naturally below
   long content. Scoped to .mmw-app so .mmw-auth (login card,
   centred with its own grid) is untouched. */
body.mmw-app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
body.mmw-app > main {
  flex: 1 0 auto;
  padding-bottom: 2rem;  /* breathing room above the footer on
                            long pages; doesn't push past 100vh
                            on short pages because main's height
                            is driven by flex-grow, not content */
}
body.mmw-app > .mmw-app-footer {
  flex-shrink: 0;
}

h1, h2, h3, .h1, .h2, .h3 {
  font-family: var(--mmw-sans);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--mmw-ink);
}

code, pre, .font-monospace {
  font-family: var(--mmw-mono) !important;
  font-size: 0.875em;
}

.btn { font-weight: 500; border-radius: 8px; }
.btn-primary {
  background: var(--mmw-ink);
  border-color: var(--mmw-ink);
}
.btn-primary:hover, .btn-primary:focus {
  background: var(--mmw-accent-ink);
  border-color: var(--mmw-accent-ink);
}
.btn-outline-secondary {
  color: var(--mmw-ink-soft);
  border-color: var(--mmw-line);
  background: transparent;
}
.btn-outline-secondary:hover {
  background: var(--mmw-line-soft);
  color: var(--mmw-ink);
  border-color: var(--mmw-line);
}
.btn-outline-danger {
  color: var(--mmw-danger);
  border-color: var(--mmw-line);
}
.btn-outline-danger:hover {
  background: #fbeceb;
  color: var(--mmw-danger);
  border-color: #f0bdbb;
}

.form-control {
  border-color: var(--mmw-line);
  background: var(--mmw-card);
  color: var(--mmw-ink);
  border-radius: 8px;
}
.form-control:focus {
  border-color: var(--mmw-ink);
  box-shadow: 0 0 0 3px rgba(21,24,28,0.08);
}

.alert { border-radius: var(--mmw-radius); border: 1px solid transparent; }
.alert-danger  { background: #fbeceb; border-color: #f0bdbb; color: var(--mmw-danger); }
.alert-success { background: #ecf3ed; border-color: #bfd6c4; color: var(--mmw-ok); }

/* Brand mark ------------------------------------------------- */
.mmw-brand {
  display: inline-flex; align-items: center; gap: .55rem;
  text-decoration: none; color: var(--mmw-ink);
}
.mmw-brand__mark {
  color: var(--mmw-accent);
  font-size: 1.1rem;
  transform: translateY(-1px);
}
.mmw-brand__name {
  font-family: var(--mmw-sans);
  font-weight: 600;
  letter-spacing: -0.01em;
  font-size: 1.1rem;
}

/* Nav bar ----------------------------------------------------
   Warm-ivory tint against the cool-white body — a small bit of
   brand character visible across every app page. */
.mmw-nav {
  background: color-mix(in srgb, var(--mmw-nav-bg) 88%, white);
  border-bottom: 1px solid var(--mmw-nav-line);
  position: sticky; top: 0; z-index: 10;
  backdrop-filter: saturate(1.1) blur(8px);
  -webkit-backdrop-filter: saturate(1.1) blur(8px);
}

/* App footer -------------------------------------------------
   Thin warm-ivory strip that bookends the page with the nav.
   Not sticky — it lives naturally below content. Uses the same
   --mmw-nav-* tokens as the header so the two stay in sync. */
.mmw-app-footer {
  background: var(--mmw-nav-bg);
  border-top: 1px solid var(--mmw-nav-line);
  padding: 1.25rem 0;
}
.mmw-app-footer__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.82rem;
  color: var(--mmw-muted);
}
.mmw-app-footer__copy { flex: 0 0 auto; }
.mmw-app-footer__links {
  display: flex;
  gap: 1.25rem;
  flex-wrap: wrap;
}
.mmw-app-footer__links a {
  color: var(--mmw-ink-soft);
  text-decoration: none;
  transition: color 0.15s ease;
}
.mmw-app-footer__links a:hover {
  color: var(--mmw-accent);
  text-decoration: none;
}
@media (max-width: 520px) {
  .mmw-app-footer__inner { justify-content: center; text-align: center; }
  .mmw-app-footer__links { justify-content: center; }
}

/* Auth card (login) ------------------------------------------ */
.mmw-auth {
  min-height: 100vh;
  display: grid; place-items: center;
  padding: 2rem 1rem;
  background:
    radial-gradient(1200px 400px at 10% -10%, rgba(196,80,43,.08), transparent 60%),
    radial-gradient(900px 500px at 90% 110%, rgba(21,24,28,.05), transparent 60%),
    var(--mmw-paper);
}
.mmw-auth__card {
  width: 100%; max-width: 420px;
  background: var(--mmw-card);
  border: 1px solid var(--mmw-line);
  border-radius: var(--mmw-radius-lg);
  padding: 2rem;
  box-shadow: var(--mmw-shadow);
}
.mmw-auth .mmw-brand { margin-bottom: 1.75rem; }

/* Cards ------------------------------------------------------ */
.mmw-card {
  background: var(--mmw-card);
  border: 1px solid var(--mmw-line);
  border-radius: var(--mmw-radius-lg);
  padding: 1.25rem 1.25rem;
  box-shadow: var(--mmw-shadow);
}

/* Push panel ------------------------------------------------- */
.mmw-textarea {
  font-family: var(--mmw-mono);
  font-size: 13.5px;
  min-height: 140px;
  resize: vertical;
}

.mmw-drop {
  position: relative;
  border: 1.5px dashed var(--mmw-line);
  border-radius: var(--mmw-radius);
  padding: 1.5rem 1rem;
  text-align: center;
  transition: border-color .15s, background .15s;
  background: var(--mmw-card);
}
.mmw-drop.is-dragover {
  border-color: var(--mmw-accent);
  background: color-mix(in srgb, var(--mmw-accent) 6%, var(--mmw-card));
}
.mmw-drop__icon {
  font-size: 1.75rem; line-height: 1;
  color: var(--mmw-accent);
  margin-bottom: .35rem;
}

.mmw-progress { margin-top: .75rem; }
.mmw-progress__bar {
  height: 6px; background: var(--mmw-line-soft);
  border-radius: 999px; overflow: hidden;
}
.mmw-progress__fill {
  height: 100%;
  background: var(--mmw-ink);
  transition: width .2s linear;
}
.mmw-progress__fill.is-warn {
  /* >=80% — soft orange so the user notices before the
     auto-delete bites. v10.57 item 3. */
  background: #e36b22;
}
/* v10.73.2: indeterminate pulse for the server→B2 transfer phase
   (phase 2). Shown while the bar sits at 100% so a large upload
   doesn't look frozen. Subtle opacity pulse — no layout shift. */
.mmw-progress__fill.is-indeterminate {
  animation: mmwProgPulse 1.1s ease-in-out infinite;
}
@keyframes mmwProgPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .4; }
}

/* Clip list -------------------------------------------------- */
.mmw-list {
  display: grid; gap: .65rem;
}
.mmw-clip {
  background: var(--mmw-card);
  border: 1px solid var(--mmw-line);
  border-radius: var(--mmw-radius);
  padding: .85rem 1rem;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: .85rem;
  align-items: start;
  transition: border-color .15s, transform .15s;
}
.mmw-clip:hover { border-color: var(--mmw-accent); }
.mmw-clip.is-new {
  animation: mmwNew 1.2s ease-out;
}
@keyframes mmwNew {
  0%   { background: color-mix(in srgb, var(--mmw-accent) 10%, var(--mmw-card)); }
  100% { background: var(--mmw-card); }
}

.mmw-clip__badge {
  font-family: var(--mmw-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .08em;
  padding: .2rem .5rem;
  border-radius: 999px;
  border: 1px solid var(--mmw-line);
  color: var(--mmw-muted);
  background: var(--mmw-paper);
  white-space: nowrap;
}
.mmw-clip__badge--link { color: var(--mmw-accent-ink); border-color: rgba(196, 80, 43, 0.25); background: rgba(196, 80, 43, 0.08); }
.mmw-clip__badge--file { color: #37526e; border-color: #c9d6e4; background: #eef3f9; }

.mmw-clip__body { min-width: 0; }
.mmw-clip__content {
  font-family: var(--mmw-mono);
  font-size: 13px;
  color: var(--mmw-ink);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 6.5em;
  overflow: hidden;
  position: relative;
}
.mmw-clip__content.is-truncated::after {
  content: '';
  position: absolute; inset: auto 0 0 0; height: 2em;
  background: linear-gradient(to bottom, rgba(255,255,255,0), #fff);
}
.mmw-clip__content a { color: var(--mmw-accent-ink); }

.mmw-clip__meta {
  font-size: 12px;
  color: var(--mmw-muted);
  margin-top: .35rem;
  display: flex; gap: .75rem; flex-wrap: wrap;
}

.mmw-clip__file {
  display: flex; gap: .75rem; align-items: center;
}
.mmw-clip__filename {
  font-weight: 500;
  word-break: break-all;
}
.mmw-clip__workroom {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  margin-top: .4rem;
  padding: 2px 8px 2px 6px;
  font-size: 11px;
  font-weight: 500;
  color: var(--mmw-accent, #c4502b);
  background: rgba(196, 80, 43, 0.08);
  border-radius: 100px;
  text-decoration: none;
  line-height: 1.6;
}
.mmw-clip__workroom:hover {
  background: rgba(196, 80, 43, 0.14);
  color: var(--mmw-accent, #c4502b);
  text-decoration: none;
}
.mmw-clip__workroom-icon {
  font-size: 10px;
  line-height: 1;
}

.mmw-clip__actions {
  display: flex; gap: .35rem; align-items: center;
}
.mmw-clip__btn {
  border: 1px solid var(--mmw-line);
  background: var(--mmw-card);
  color: var(--mmw-ink-soft);
  font-size: 12px;
  padding: .3rem .6rem;
  border-radius: 6px;
  cursor: pointer;
  transition: all .12s;
}
.mmw-clip__btn:hover { background: var(--mmw-line-soft); color: var(--mmw-ink); }
.mmw-clip__btn--danger:hover { background: #fbeceb; color: var(--mmw-danger); border-color: #f0bdbb; }

.mmw-empty {
  text-align: center;
  padding: 3rem 1rem;
  border: 1px dashed var(--mmw-line);
  border-radius: var(--mmw-radius);
  background: transparent;
}

/* Connection status ----------------------------------------- */
.mmw-status {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: 12px; color: var(--mmw-muted);
  font-family: var(--mmw-mono);
}
.mmw-status__dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--mmw-muted);
  box-shadow: 0 0 0 0 currentColor;
}
.mmw-status.is-live .mmw-status__dot {
  background: var(--mmw-ok);
  animation: mmwPulse 2.4s ease-in-out infinite;
}
.mmw-status.is-error .mmw-status__dot { background: var(--mmw-danger); }
@keyframes mmwPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(47,107,58,.35); }
  50%      { box-shadow: 0 0 0 6px rgba(47,107,58,0);   }
}

/* Toast ------------------------------------------------------ */
.mmw-toast {
  position: fixed;
  left: 50%; bottom: 24px; transform: translateX(-50%) translateY(20px);
  /* Inverted "pill": the background tracks the body-text colour and the
     text tracks the page background, so it stays high-contrast in BOTH
     themes. Pairing var(--mmw-ink) with a FIXED #fff broke dark mode —
     the pill flipped to warm-ivory but the text stayed white (illegible).
     The colour-coded variants below re-assert white text on their own
     strong backgrounds. */
  background: var(--mmw-ink); color: var(--mmw-paper);
  padding: .75rem 1.2rem;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  box-shadow: 0 10px 30px -12px rgba(0,0,0,.4);
  opacity: 0; pointer-events: none;
  transition: transform .2s ease, opacity .2s ease;
  z-index: 50;
  max-width: calc(100vw - 2rem);
  text-align: center;
}
.mmw-toast.is-visible {
  opacity: 1; transform: translateX(-50%) translateY(0);
}
.mmw-toast.is-error { background: var(--mmw-danger); color: #fff; }
.mmw-toast.is-success {
  background: var(--mmw-success, #2f6b3a);
  color: #fff;
}

/* Upload drop-zone success state --------------------------- */
.mmw-drop.is-success {
  border-color: var(--mmw-success, #2f6b3a);
  background: rgba(47, 107, 58, 0.08);
}
.mmw-drop__status {
  margin-top: 0.75rem;
  padding: 0.5rem 0.75rem;
  background: rgba(47, 107, 58, 0.12);
  border-radius: 8px;
  color: var(--mmw-success, #2f6b3a);
  font-weight: 600;
  font-size: 14px;
  text-align: center;
}
.mmw-drop.is-success #uploadProgressText {
  color: var(--mmw-success, #2f6b3a) !important;
  font-weight: 600;
}

/* File-row styles (used on files.php) ------------------------ */
/* v10.71: cleaner, mobile-first layout. The previous version
   used Bootstrap d-flex utilities directly on the <li>, which on
   narrow screens caused the filename link to balloon and the
   metadata row to wrap awkwardly. This explicit layout truncates
   filenames with ellipsis, keeps metadata on a single line that
   line-wraps cleanly, and gives the icon column a fixed width so
   the whole list aligns. */
.mmw-file-list {
  margin: 0;
}
.mmw-file-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 0;
  border-bottom: 1px solid var(--mmw-line);
}
.mmw-file-row:last-child {
  border-bottom: none;
}
.mmw-file-row__icon {
  flex: 0 0 24px;
  font-size: 20px;
  line-height: 1.4;
  text-align: center;
}
.mmw-file-row__body {
  flex: 1 1 auto;
  min-width: 0;   /* let the children truncate; without this the
                     flex item refuses to shrink past content width */
}
.mmw-file-row__name {
  color: var(--mmw-ink);
  font-weight: 500;
  text-decoration: none;
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}
.mmw-file-row__name:hover {
  color: var(--mmw-accent);
  text-decoration: underline;
}
.mmw-file-row__name--archived {
  color: var(--mmw-muted);
}
.mmw-file-row__badge {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 500;
  background: var(--mmw-line-soft);
  color: var(--mmw-ink-soft);
  border-radius: 999px;
  vertical-align: 2px;
}
.mmw-file-row__meta {
  margin-top: 2px;
  color: var(--mmw-muted);
  font-size: 12.5px;
  line-height: 1.55;
  display: flex;
  flex-wrap: wrap;
  gap: 0 6px;
}
.mmw-file-row__sep {
  color: var(--mmw-muted);
  opacity: 0.5;
}

/* v10.71.4: theme toggle button in the nav. Sits to the left of
   Sign out. Compact (~32px square) so it doesn't strain the
   mobile nav budget. Icon is a Unicode character ('☀ / ☾ / ⚙')
   rendered via the .mmw-nav__theme-icon span. */
.mmw-nav__theme-btn {
  width: 32px;
  height: 32px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.mmw-nav__theme-icon {
  font-size: 15px;
  line-height: 1;
  /* The cog/gear (⚙) is wider than the sun/moon so without
     this it would shift the button width subtly. Fixing the
     containing span's width keeps things still. */
  display: inline-block;
  width: 16px;
  text-align: center;
}

/* v10.71.5: per-row checkbox column. Sits to the left of the
   icon. Hidden visually but tap-target-friendly via the
   label wrapper. */
.mmw-file-row__check {
  flex: 0 0 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 4px 0;
  margin: -4px 0;   /* expands the hit area without affecting layout */
}
.mmw-file-row__checkbox {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--mmw-accent);
}

/* "Select all" toggle for each section heading. */
.mmw-files-selectall {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--mmw-muted);
  cursor: pointer;
  user-select: none;
}
.mmw-files-selectall input {
  accent-color: var(--mmw-accent);
}

/* Bulk action bar — appears under the page header when 1+ files
   are selected anywhere on the page. Sticky so it stays
   reachable as the user scrolls a long list.

   v10.71.6: explicit `[hidden]` rule — `display: flex` below has
   equal specificity to the UA `[hidden] { display: none }` and
   loaded LATER, so it was winning and the bar stayed visible
   even with the `hidden` attribute set. Belt-and-braces fix:
   `[hidden]` rule with same selector specificity declared after
   the base rule, plus the bar's render code in files.php also
   toggles a class as a fallback.

   v10.71.11: renamed from .mmw-bulk-bar to .mmw-files-bulk to
   avoid colliding with the dashboard's selection bar, which has
   used .mmw-bulk-bar since v10.57 with a completely different
   design (fixed-position floating pill at bottom of viewport).
   The class collision was producing a giant black oval on the
   dashboard. */
.mmw-files-bulk {
  position: sticky;
  top: 8px;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  margin-bottom: 1rem;
  background: var(--mmw-card);
  border: 1px solid var(--mmw-line);
  border-radius: 10px;
  box-shadow: var(--mmw-shadow);
  flex-wrap: wrap;
}
.mmw-files-bulk[hidden] { display: none; }
.mmw-files-bulk__count {
  font-size: 14px;
  color: var(--mmw-ink);
}
.mmw-files-bulk__actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

/* v10.71.6: per-row actions on the Files page — Download + Delete
   buttons appear at the right of each file row. Hover/focus on the
   row reveals them; on touch devices they're always visible (no
   hover). The bulk bar above still works for multi-select, but
   single-file operations don't require ticking a checkbox first. */
.mmw-file-row__actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  margin-left: 8px;
  opacity: 1;        /* always visible by default — invisible-until-hover
                        is too clever for mobile, hides discoverability */
}
.mmw-file-row__actions .btn {
  padding: 2px 8px;
  font-size: 12px;
}

/* v10.71.10: Connections list on the Settings page (and the
   picker in the Share & Members tab — same component, different
   container). One row per connection with name, email, and a
   "via <workroom>" hint plus a Remove (or Add) action button. */
.mmw-conn-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.mmw-conn-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: var(--mmw-card);
  border: 1px solid var(--mmw-line);
  border-radius: 8px;
}
.mmw-conn-row__body {
  flex: 1;
  min-width: 0;
}
.mmw-conn-row__name {
  font-weight: 500;
  color: var(--mmw-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mmw-conn-row__meta {
  font-size: 12px;
  color: var(--mmw-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mmw-conn-row__sep {
  margin: 0 6px;
  opacity: 0.5;
}
.mmw-conn-via {
  font-style: italic;
}

/* Pending invites banner on the Dashboard (v10.71.10). Sits at
   the top of the page when there are 1+ workroom invites
   awaiting Accept / Decline. Uses the accent border-left to
   match other contextual blocks in the app. */
.mmw-pending-invites {
  background: color-mix(in srgb, var(--mmw-accent) 6%, var(--mmw-card));
  border: 1px solid var(--mmw-line);
  border-left: 3px solid var(--mmw-accent);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 1rem;
}
.mmw-pending-invites__title {
  font-weight: 500;
  color: var(--mmw-ink);
  margin-bottom: 8px;
}
.mmw-pending-invites__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.mmw-pending-invite {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 10px;
  background: var(--mmw-card);
  border: 1px solid var(--mmw-line);
  border-radius: 6px;
  flex-wrap: wrap;
}
.mmw-pending-invite__text {
  flex: 1;
  min-width: 0;
  font-size: 14px;
  color: var(--mmw-ink);
}
.mmw-pending-invite__actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

/* Responsive tweaks ----------------------------------------- */

/* v10.70: the nav partial uses two helper classes:
   - .mmw-nav__btn--desktop-only — hide on narrow screens (these
     links also live in the More dropdown)
   - .mmw-nav__more--mobile-only — show the hamburger ONLY on
     narrow screens (it's redundant when all links fit inline)
   Defaults below: desktop hides the More button. The mobile media
   query inverts both. */
.mmw-nav__more--mobile-only { display: none; }

/* The More dropdown itself — uses native <details>/<summary> so
   keyboard + screen-reader behaviour is correct without any JS.
   Positioned absolutely so the open panel overlays the page
   content rather than reflowing it. */
.mmw-nav__more {
  position: relative;
}
.mmw-nav__more > summary {
  list-style: none;            /* hide the default disclosure triangle */
  cursor: pointer;
  user-select: none;
}
.mmw-nav__more > summary::-webkit-details-marker { display: none; }
.mmw-nav__more > summary::marker                  { display: none; }

.mmw-nav__more-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 180px;
  background: var(--mmw-card);
  border: 1px solid var(--mmw-line);
  border-radius: 10px;
  box-shadow: var(--mmw-shadow);
  padding: 6px 0;
  z-index: 50;
}
.mmw-nav__more-link {
  display: block;
  padding: 0.5rem 0.9rem;
  font-size: 14px;
  color: var(--mmw-accent);   /* matches the primary buttons */
  text-decoration: none;
}
.mmw-nav__more-link:hover {
  background: var(--mmw-line-soft);
}
.mmw-nav__more-link--secondary {
  color: var(--mmw-ink-soft);
}
.mmw-nav__more-link--danger {
  color: var(--mmw-danger);
  border-top: 1px solid var(--mmw-line);
  margin-top: 4px;
  padding-top: 0.6rem;
}

@media (max-width: 576px) {
  .mmw-clip { grid-template-columns: 1fr; }
  .mmw-clip__actions { justify-content: flex-end; }
  .mmw-toast {
    bottom: 16px;
    font-size: 13px;
    padding: .6rem 1rem;
  }

  /* Header: on narrow phones the full logo+wordmark plus status
     badge plus all buttons don't fit. The nav partial collapses
     intermediate links (Files, Calendar, Settings, Dashboard) into
     a "More" dropdown; only the brand, Workrooms, and Sign out
     remain visible inline. New features can join the dropdown
     without disturbing the header layout. */
  .mmw-brand__name { display: none; }
  .mmw-status      { display: none !important; }

  /* Hide buttons marked desktop-only — they live in the More
     dropdown on mobile. */
  .mmw-nav__btn--desktop-only { display: none !important; }

  /* Show the More dropdown's trigger. */
  .mmw-nav__more--mobile-only { display: inline-block; }

  /* Tighten spacing so what remains fits on 375px devices. */
  .mmw-nav .gap-2,
  .mmw-nav .gap-3    { gap: 0.35rem !important; }
  .mmw-nav .btn-sm   { padding: 0.25rem 0.55rem; font-size: 13px; }
  .mmw-nav { padding: 0.25rem 0; }

  /* Container shouldn't wrap on the narrowest viewports. */
  .mmw-nav .container-xl { flex-wrap: nowrap; }
}

/* Modal (share dialog) -------------------------------------- */
.mmw-modal__overlay {
  position: fixed; inset: 0;
  background: rgba(21, 24, 28, 0.55);
  display: grid; place-items: center;
  z-index: 100;
  padding: 1rem;
  animation: mmwFade 0.15s ease-out;
}
@keyframes mmwFade { from { opacity: 0; } to { opacity: 1; } }

.mmw-modal {
  background: var(--mmw-card);
  border: 1px solid var(--mmw-line);
  border-radius: var(--mmw-radius-lg);
  box-shadow: 0 20px 60px -20px rgba(0, 0, 0, 0.35);
  width: 100%;
  max-width: 460px;
  max-height: 90vh;
  overflow: auto;
  animation: mmwPop 0.18s cubic-bezier(.2,.9,.3,1);
}
@keyframes mmwPop {
  from { transform: translateY(12px) scale(.98); opacity: 0; }
  to   { transform: translateY(0) scale(1);      opacity: 1; }
}

.mmw-modal__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.1rem 1.25rem 0.9rem;
  border-bottom: 1px solid var(--mmw-line-soft);
}
.mmw-modal__close {
  background: none; border: 0; color: var(--mmw-muted);
  font-size: 1.6rem; line-height: 1; cursor: pointer;
  padding: 0 .3rem; border-radius: 6px;
}
.mmw-modal__close:hover { background: var(--mmw-line-soft); color: var(--mmw-ink); }

.mmw-modal__body { padding: 1.1rem 1.25rem 1.25rem; }

/* Share-to-workroom modal: radio list of the user's rooms.
   Each row is a clickable label with the radio hidden-but-
   present for keyboard and screen-reader users. Matches the
   .mmw-join-mode__opt pattern used in workroom settings. */
.mmw-tw-room-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-bottom: 1rem;
  max-height: 240px;
  overflow-y: auto;
}
.mmw-tw-room {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--mmw-line);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
.mmw-tw-room:hover { border-color: #c7cbd1; }
.mmw-tw-room input[type="radio"] {
  margin: 0;
  flex-shrink: 0;
  accent-color: var(--mmw-accent);
}
.mmw-tw-room:has(input:checked) {
  border-color: var(--mmw-accent);
  background: rgba(196, 80, 43, 0.04);
}
.mmw-tw-room__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.mmw-tw-room__name {
  font-weight: 500;
  color: var(--mmw-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mmw-tw-room__meta { font-family: var(--mmw-mono, monospace); }

/* Preview box in the share-to-workroom modal.
   For file clips, contains the filename + size (inline).
   For text/link clips, contains a truncated preview of the
   content — quoted-looking so it's clearly distinct from
   the modal's own chrome. */
.mmw-tw-preview {
  padding: 0.55rem 0.75rem;
  background: var(--mmw-line-soft);
  border-left: 3px solid var(--mmw-line);
  border-radius: 0 6px 6px 0;
  font-size: 13px;
  color: var(--mmw-ink-soft);
  word-break: break-word;
  max-height: 120px;
  overflow-y: auto;
}
.mmw-tw-textpreview {
  white-space: pre-wrap;
  font-family: inherit;
}

/* Shared-clip page (s.php) ---------------------------------- */
.mmw-share-page .mmw-card { padding: 1.5rem; }

/* =============================================================
   Bulk selection (v10.49)
   Checkbox overlay on each clip card + floating action bar.
   ============================================================= */

/* Give the card position:relative so the absolutely-positioned
   checkbox overlay anchors to it. */
.mmw-clip { position: relative; }

/* The checkbox sits at the top-left corner, overlapping the
   badge. On desktop it fades in on hover (unobtrusive) and
   fades up when the card IS selected; on touch devices it's
   always visible because there's no hover. */
.mmw-clip__select {
  position: absolute;
  top: 8px;
  left: 8px;
  width: 22px;
  height: 22px;
  margin: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.12s ease;
  z-index: 2;
}
/* Show on card hover (desktop) */
.mmw-clip:hover .mmw-clip__select,
/* and always when ANY clip is selected — gives users a clear
   signal that they're in a multi-select context, and lets
   them tick more cards without re-hovering each one. */
.mmw-list:has(.mmw-clip--selected) .mmw-clip__select,
/* and always while the checkbox is focused (keyboard nav). */
.mmw-clip__select:focus-within {
  opacity: 1;
}

/* The real <input> is visually hidden but still receives focus
   and click. A styled <span> renders in its place. */
.mmw-clip__checkbox {
  position: absolute;
  opacity: 0;
  width: 22px;
  height: 22px;
  margin: 0;
  cursor: pointer;
}
.mmw-clip__select-indicator {
  width: 20px;
  height: 20px;
  border: 1.5px solid var(--mmw-line);
  border-radius: 5px;
  background: var(--mmw-card);
  transition: background 0.12s, border-color 0.12s;
  position: relative;
}
.mmw-clip__checkbox:hover + .mmw-clip__select-indicator,
.mmw-clip__checkbox:focus-visible + .mmw-clip__select-indicator {
  border-color: var(--mmw-accent);
}
.mmw-clip__checkbox:checked + .mmw-clip__select-indicator {
  background: var(--mmw-accent);
  border-color: var(--mmw-accent);
}
/* Checkmark glyph when checked (CSS pseudo, no image) */
.mmw-clip__checkbox:checked + .mmw-clip__select-indicator::after {
  content: "";
  position: absolute;
  left: 5px;
  top: 1px;
  width: 6px;
  height: 12px;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(45deg);
}

/* Selected card: tint border + soft background so the state is
   visible at a glance, even without looking at the tiny checkbox. */
.mmw-clip--selected {
  border-color: var(--mmw-accent);
  background: color-mix(in srgb, var(--mmw-accent) 5%, var(--mmw-card));
}

/* Ensure the badge isn't hidden by the checkbox on narrow cards —
   shift badge right when the hoverable checkbox has room. The
   badge already uses its own grid cell so this is mostly a safety
   tweak for cards that wrap unexpectedly. */
.mmw-clip > .mmw-clip__badge {
  margin-left: 24px;  /* room for the 22px checkbox + 2px gap */
}

/* Touch devices: always show the checkbox (no hover event). */
@media (hover: none) {
  .mmw-clip__select {
    opacity: 1;
  }
}

/* ---- Floating bulk action bar ------------------------------- */

.mmw-bulk-bar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  bottom: 16px;
  z-index: 1100;
  background: var(--mmw-ink);
  color: var(--mmw-card);
  border-radius: 999px;
  padding: 10px 14px 10px 20px;
  display: flex;
  align-items: center;
  gap: 16px;
  box-shadow: 0 12px 32px -8px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity 0.18s ease, transform 0.18s ease;
  max-width: calc(100vw - 32px);
}
.mmw-bulk-bar.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.mmw-bulk-bar[hidden] { display: none !important; }

.mmw-bulk-bar__count {
  font-weight: 500;
  white-space: nowrap;
}

.mmw-bulk-bar__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.mmw-bulk-bar__btn {
  background: rgba(255, 255, 255, 0.15);
  color: inherit;
  border: 0;
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 0.88rem;
  cursor: pointer;
  transition: background 0.12s;
  white-space: nowrap;
}
.mmw-bulk-bar__btn:hover { background: rgba(255, 255, 255, 0.25); }
.mmw-bulk-bar__btn--danger {
  background: rgba(196, 80, 43, 0.85);
}
.mmw-bulk-bar__btn--danger:hover { background: rgba(196, 80, 43, 1); }
.mmw-bulk-bar__btn--ghost {
  background: transparent;
}
.mmw-bulk-bar__btn--ghost:hover { background: rgba(255, 255, 255, 0.12); }

/* Add breathing room at the bottom of the page when the bar is
   up so content isn't hidden behind it. */
body.mmw-has-bulk-bar {
  padding-bottom: 80px;
}

@media (max-width: 575.98px) {
  .mmw-bulk-bar {
    bottom: 10px;
    padding: 8px 10px 8px 14px;
    gap: 10px;
  }
  .mmw-bulk-bar__count { font-size: 0.9rem; }
  .mmw-bulk-bar__btn { padding: 5px 10px; font-size: 0.82rem; }
}

/* =============================================================
   Image thumbnails on Recent Clips (v10.50)
   A small square thumbnail to the left of the filename for
   image-MIME file clips. Clicking opens the shared lightbox.
   ============================================================= */
.mmw-clip__thumb {
  display: block;
  flex-shrink: 0;
  width: 72px;
  height: 72px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--mmw-bg, #f5f5f7);
  border: 1px solid var(--mmw-line, #e4e6e9);
  cursor: zoom-in;
  transition: transform 0.12s ease, border-color 0.12s ease;
  position: relative;
}
.mmw-clip__thumb:hover {
  transform: scale(1.03);
  border-color: var(--mmw-accent, #c4502b);
}
.mmw-clip__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* If the <img> fails to load (file deleted / tombstoned) the
   onerror handler adds --broken; we hide the image and show a
   small placeholder glyph so the layout doesn't shift. */
.mmw-clip__thumb--broken img { display: none; }
.mmw-clip__thumb--broken::after {
  content: "🖼";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  opacity: 0.35;
}

/* YouTube preview tile styles moved to /assets/youtube-tile.css
   in v10.52 so workroom chat can share them. The YouTube tile JS
   module is /assets/youtube-tile.js. */

/* =============================================================
   Quota banner (v10.57 item 3) — shown on the dashboard when
   the user is close to or over the clip-count limit. Hidden by
   default; app.js toggles visibility + variant based on
   window.MMW_CLIP_COUNT / MMW_CLIP_LIMIT.
   ============================================================= */
.mmw-quota-banner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 16px;
}
.mmw-quota-banner__title { font-weight: 600; }
.mmw-quota-banner__detail { flex: 1; min-width: 200px; }
.mmw-quota-banner__link { font-weight: 500; }

/* Warning variant: orange, 80–99% of limit. */
.mmw-quota-banner.is-warn {
  background: #fff4ec;
  color: #8a3c0c;
  border: 1px solid #f6c694;
}
.mmw-quota-banner.is-warn .mmw-quota-banner__link {
  color: #8a3c0c;
  text-decoration: underline;
}

/* Full variant: red, at-or-over the limit. */
.mmw-quota-banner.is-full {
  background: #fdeceb;
  color: #8a2a25;
  border: 1px solid #f0bdbb;
}
.mmw-quota-banner.is-full .mmw-quota-banner__link {
  color: #8a2a25;
  text-decoration: underline;
}

/* =============================================================
   Quota strip (v10.59) — compact "where am I at" line beneath
   the Recent clips header. Always visible, no progress bars
   (those live in Settings). Just numbers + a Manage link.
   ============================================================= */
.mmw-quota-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 10px;
  /* Subtle background so the strip reads as informational
     metadata rather than competing with the actual clip list
     below. Uses --mmw-line-soft so it dark-modes correctly;
     the old --mmw-bg variable wasn't defined and fell back to
     a hardcoded cream that leaked into dark mode. */
  padding: 6px 10px;
  background: var(--mmw-line-soft);
  border-radius: 8px;
}
.mmw-quota-strip__item strong {
  /* Numbers get the ink colour so they stand out from the
     muted label text. */
  color: var(--mmw-ink, #14171a);
  font-weight: 600;
}
.mmw-quota-strip__sep {
  opacity: 0.5;
}
.mmw-quota-strip__link {
  /* Push to the far right when there's room; on narrow phones
     it wraps to its own line via flex-wrap above. */
  margin-left: auto;
  color: var(--mmw-accent, #c4502b);
  text-decoration: none;
  font-weight: 500;
}
.mmw-quota-strip__link:hover {
  text-decoration: underline;
}
/* Warn state: 80%+ of either limit. Subtle orange tint —
   matches the quota banner colour family. */
/* v10.73 (Spec 2): warn/full states now use tokens so they adapt to
   dark mode (previously hardcoded warm cream / red). */
.mmw-quota-strip.is-warn {
  background: color-mix(in srgb, var(--mmw-accent) 12%, var(--mmw-card));
  color: var(--mmw-accent-ink);
}
.mmw-quota-strip.is-warn .mmw-quota-strip__item strong {
  color: var(--mmw-accent-ink);
}
/* Full state: at/over the limit. */
.mmw-quota-strip.is-full {
  background: color-mix(in srgb, var(--mmw-danger) 14%, var(--mmw-card));
  color: var(--mmw-danger);
}
.mmw-quota-strip.is-full .mmw-quota-strip__item strong {
  color: var(--mmw-danger);
}

/* ============================================================
   Admin section (/admin/). v10.73.
   Reuses the app tokens (cards, lines, accent) so the admin area
   feels like the same product. Works in light + dark via --mmw-*.
   ============================================================ */

/* "Admin" pill in the nav brand. */
.mmw-admin-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #fff;
  background: var(--mmw-accent);
  border-radius: 999px;
  vertical-align: middle;
}

/* Responsive grid of headline stat cards. */
.mmw-admin-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
}
.mmw-stat {
  background: var(--mmw-card);
  border: 1px solid var(--mmw-line);
  border-radius: var(--mmw-radius);
  padding: 1rem 1.1rem;
  min-width: 0;
}
.mmw-stat__num {
  font-size: 1.7rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--mmw-ink);
}
.mmw-stat__label {
  font-size: .8rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--mmw-muted);
  margin-top: 2px;
}
.mmw-stat__sub {
  font-size: .8rem;
  color: var(--mmw-muted);
  margin-top: 4px;
}

/* Mini stat cluster (inside a card). */
.mmw-mini__num { font-size: 1.25rem; font-weight: 600; color: var(--mmw-ink); }
.mmw-mini__label { font-size: .72rem; color: var(--mmw-muted); }

/* Simple CSS bar — no charting lib. */
.mmw-admin-bar {
  height: 8px;
  background: var(--mmw-line-soft);
  border-radius: 999px;
  overflow: hidden;
}
.mmw-admin-bar__fill {
  height: 100%;
  background: var(--mmw-accent);
  border-radius: 999px;
}

/* Compact tables on the admin pages pick up the app tokens. */
.mmw-admin-table { color: var(--mmw-ink); }
.mmw-admin-table thead th {
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--mmw-muted);
  border-bottom: 1px solid var(--mmw-line);
}
.mmw-admin-table td,
.mmw-admin-table th { border-color: var(--mmw-line); }

/* Small status / tier tags. */
.mmw-admin-tag {
  display: inline-block;
  padding: 1px 7px;
  font-size: 11px;
  font-weight: 500;
  border-radius: 6px;
  background: var(--mmw-line-soft);
  color: var(--mmw-ink-soft);
}
.mmw-admin-tag--pro {
  background: color-mix(in srgb, var(--mmw-accent) 16%, var(--mmw-card));
  color: var(--mmw-accent-ink);
}
.mmw-admin-tag--admin {
  background: color-mix(in srgb, var(--mmw-ok) 18%, var(--mmw-card));
  color: var(--mmw-ok);
}
/* Spec 4: active Stripe subscription flag in admin/users.php. Blue/indigo
   so it reads as "billing system", distinct from the Pro tier tag. */
.mmw-admin-tag--stripe {
  background: color-mix(in srgb, #635bff 18%, var(--mmw-card));
  color: #635bff;
}

/* Broadcast preview block on admin/broadcast.php. */
.mmw-broadcast-preview {
  border: 1px solid var(--mmw-line);
  border-left: 3px solid var(--mmw-accent);
  border-radius: 8px;
  padding: 12px 14px;
  background: color-mix(in srgb, var(--mmw-accent) 5%, var(--mmw-card));
}
.mmw-broadcast-preview__title { font-weight: 600; color: var(--mmw-ink); margin-bottom: 4px; }
.mmw-broadcast-preview__body  { font-size: 14px; color: var(--mmw-ink-soft); }

/* ============================================================
   "What's New" announcement banner on the dashboard. v10.73.
   Matches the pending-invites banner styling (accent border-left)
   with a dismiss × on the right.
   ============================================================ */
.mmw-announcement {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: color-mix(in srgb, var(--mmw-accent) 6%, var(--mmw-card));
  border: 1px solid var(--mmw-line);
  border-left: 3px solid var(--mmw-accent);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 1rem;
}
.mmw-announcement__body { flex: 1; min-width: 0; }
.mmw-announcement__title {
  font-weight: 600;
  color: var(--mmw-ink);
  margin-bottom: 4px;
}
.mmw-announcement__text {
  font-size: 14px;
  color: var(--mmw-ink-soft);
}
.mmw-announcement__close {
  flex-shrink: 0;
  border: none;
  background: transparent;
  color: var(--mmw-muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.mmw-announcement__close:hover { color: var(--mmw-ink); }

/* ============================================================
   Tiers (Spec 2) — plan badges, quota-strip chip, upgrade nudges.
   Token-driven so they work in light + dark.
   ============================================================ */

/* Plan badge ("Free" / "Pro") used on Files + Settings. */
.mmw-tier-badge {
  display: inline-block;
  padding: 1px 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .03em;
  border-radius: 999px;
  background: var(--mmw-line-soft);
  color: var(--mmw-ink-soft);
  vertical-align: middle;
}
.mmw-tier-badge--pro {
  background: color-mix(in srgb, var(--mmw-accent) 16%, var(--mmw-card));
  color: var(--mmw-accent-ink);
}

/* Tier chip inside the dashboard quota strip. */
.mmw-tier-chip { font-weight: 500; }

/* Shared "PRO" badge (SPEC3B item 6). ONE class used everywhere Pro
   membership is surfaced — nav (next to the username), Settings, and
   the storage meters. Subtle terracotta, not a gold trophy. Free users
   get NO badge — absence is the signal. Token-driven so it reads well
   in light + dark. */
.mmw-pro-badge {
  display: inline-block;
  padding: 1px 7px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .08em;
  line-height: 1.6;
  border-radius: 5px;
  text-transform: uppercase;
  background: color-mix(in srgb, var(--mmw-accent) 16%, var(--mmw-card));
  color: var(--mmw-accent-ink, var(--mmw-accent));
  border: 1px solid color-mix(in srgb, var(--mmw-accent) 35%, transparent);
  vertical-align: middle;
  white-space: nowrap;
}

/* SPEC3B item 5: calendar.php in the workroom quick-view iframe
   (?embed=1) drops the app nav, so trim the page's top/bottom padding
   to fill the slide-over cleanly. Two-class specificity beats the
   Bootstrap .py-4 utility on the <main>. */
.mmw-cal-embed .mmw-cal {
  padding-top: 1rem;
  padding-bottom: 1.5rem;
}

/* "Upgrade" link in the quota strip — accent, a touch more prominent
   than the plain Manage link next to it. */
.mmw-quota-strip__upgrade {
  color: var(--mmw-accent-ink);
  font-weight: 600;
}

/* Inline upgrade nudge (NOT a modal) — shown when a Free user hits a
   limit (file too big, quota full, room cap). Accent-tinted, with a
   clear link to the pricing page. */
.mmw-upgrade-nudge {
  margin-top: .6rem;
  padding: 8px 12px;
  font-size: 13.5px;
  background: color-mix(in srgb, var(--mmw-accent) 8%, var(--mmw-card));
  border: 1px solid var(--mmw-line);
  border-left: 3px solid var(--mmw-accent);
  border-radius: 8px;
  color: var(--mmw-ink-soft);
}
.mmw-upgrade-nudge__link {
  white-space: nowrap;
  font-weight: 600;
  color: var(--mmw-accent-ink);
  text-decoration: none;
}
.mmw-upgrade-nudge__link:hover { text-decoration: underline; }
