  .tree-section-label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) 0;
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--gray-mid);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-bottom: 1px solid var(--gray-light);
    margin-bottom: var(--space-2);
  }
  .tree-node {
    border: 0.5px solid transparent;
    border-radius: 12px;
    margin-bottom: 0;
    overflow: hidden;
    box-shadow: 0 4px 20px rgba(0,0,0,0.06), 0 1px 6px rgba(0,0,0,0.03);
    transition: box-shadow 150ms ease, border-color 150ms ease;
  }
  .tree-node:hover {
    box-shadow: 0 8px 30px rgba(0,0,0,0.1), 0 2px 8px rgba(0,0,0,0.04);
    border-color: var(--navy);
  }
  .tree-node-header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    cursor: pointer;
    user-select: none;
  }
  .tree-node-header:hover { background: var(--gray-light); }
  .tree-toggle {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    color: var(--gray-mid);
    transition: transform 0.2s;
  }
  .tree-toggle.expanded { transform: rotate(90deg); }
  .tree-node-info { flex: 1; min-width: 0; }
  .tree-node-title {
    font-size: var(--text-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--navy);
    line-height: 1.3;
  }
  .tree-node-meta {
    font-size: var(--text-xs);
    color: var(--gray-mid);
    margin-top: 1px;
  }
  .tree-node-progress {
    font-size: var(--text-xs);
    color: var(--ink-2);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
  }
  .tree-children {
    display: none;
    border-top: 1px solid var(--gray-light);
  }
  .tree-children.open { display: block; }
  .tree-kit {
    padding: var(--space-2) var(--space-4) var(--space-2) var(--space-8);
    border-bottom: 1px solid var(--gray-light);
  }
  .tree-kit:last-child { border-bottom: none; }
  .tree-kit-header {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) 0;
    cursor: pointer;
    user-select: none;
  }
  .tree-kit-header:hover .tree-kit-title { color: var(--text-brand); }
  .tree-kit-title {
    font-size: var(--text-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--navy);
    flex: 1;
    transition: color 0.15s;
  }
  .tree-kit-meta {
    font-size: 11px;
    color: var(--gray-mid);
    white-space: nowrap;
  }
  .tree-products {
    display: none;
    padding: var(--space-1) 0 var(--space-2) var(--space-5);
  }
  .tree-products.open { display: block; }
  .tree-product {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-2) 0;
    font-size: var(--text-sm);
  }
  .tree-product a {
    text-decoration: none;
    transition: color 0.15s;
  }
  .tree-product a:hover { text-decoration: underline; }
  .product-completed a { color: var(--text-success); }
  .product-in-progress a, .product-in_progress a { color: var(--pink); font-weight: var(--font-weight-medium); }
  .product-not-started a, .product-not_started a { color: var(--navy); }

  .tree-step-check {
    color: var(--text-success);
    flex-shrink: 0;
    margin-top: 1px;
  }
  .tree-step-number {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    flex-shrink: 0;
    margin-top: 1px;
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    color: var(--ink-2);
  }
  .tree-step-bullet {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--gray-light);
    flex-shrink: 0;
    margin-top: var(--space-1-5);
  }
  .tree-step-content {
    flex: 1;
    min-width: 0;
  }
  .tree-step-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
  }
  .tree-step-row > a:first-child {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .tree-step-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-shrink: 0;
  }
  .tree-step-start {
    font-size: var(--text-sm);
    color: var(--pink) !important;
    text-decoration: underline !important;
    white-space: nowrap;
  }
  .tree-step-start:hover {
    color: var(--pink) !important;
  }
  .tree-step-menu-wrap {
    position: relative;
  }
  .tree-step-menu-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border: none;
    background: none;
    color: var(--ink-2);
    cursor: pointer;
    border-radius: var(--radius-sm);
    padding: 0;
  }
  .tree-step-menu-btn:hover {
    background: var(--bg-secondary);
  }
  .tree-step-dropdown {
    display: none;
    position: absolute;
    right: 0;
    top: 100%;
    background: var(--white);
    border: 1px solid var(--gray-light);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    min-width: 150px;
    z-index: 100;
    padding: var(--space-1) 0;
  }
  .tree-step-menu-wrap.open .tree-step-dropdown {
    display: block;
  }
  .tree-step-dropdown-item {
    display: block;
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    color: var(--navy) !important;
    text-decoration: none !important;
    white-space: nowrap;
  }
  .tree-step-dropdown-item:hover {
    background: var(--bg-secondary);
  }
  .tree-step-date {
    font-size: var(--text-xs);
    color: var(--ink-2);
    margin-top: 2px;
  }
  .tree-step-locked {
    opacity: 0.45;
  }
  .tree-step-label-locked {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--ink-2);
  }

  .home-activity-page .activity-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }

  .home-activity-page .tree-node-header {
    height: 80px;
    box-sizing: border-box;
  }

/* ============================================================
   My Work page chrome — shared by Files (work.html) and
   Projects (work_projects.html) tabs. Tokenized for theming.
   ============================================================ */

.mw-page {
  max-width: 1390px;
  margin: 0 auto;
  padding: 0 var(--space-6) var(--page-padding-bottom);
}

/* Inner detail pages (project, kit, program participant) render in a
   slightly narrower 1310px container. */
.mw-page.mw-page--detail {
  max-width: 1310px;
}

/* Soft navigation from a non-app page (home / free / explore /
   pricing) drops the My Work content directly into <body>'s
   #spaContent without recreating the .app-layout > .main-content >
   .page-content shell that normally provides 48px of top padding.
   Without that padding the heading on legacy /work tabs (Projects,
   Library, Program participant) slides under the fixed top bar
   until a refresh restores the shell. Re-add the equivalent top
   padding only in the wrapper-less case so a fresh load is unchanged.
   Free/Explore are excluded — they carry .free-page and have their
   own .listing-hero band. Pages that already render a .listing-hero
   are also excluded — the panel's own 100px margin + topbar-height
   padding clears the navbar, and adding 48px on top stacks visibly
   during soft-nav (large gap → settles smaller after body class swap),
   reading as a "header layout flash" between navbar tabs. */
body:not(.v2-app) > #spaContent > .mw-page:not(.free-page):not(:has(> .listing-hero, > #mw-tab-content > .listing-hero)) {
  padding-top: var(--space-3xl);
}
@media (max-width: 768px) {
  body:not(.v2-app) > #spaContent > .mw-page:not(.free-page):not(:has(> .listing-hero, > #mw-tab-content > .listing-hero)) {
    padding-top: var(--space-xl);
  }
}

/* My Work pages now sit on a plain white surface (gradient removed
   per design). Kept as a single rule so /free + /explore (which also
   carry .mw-page) inherit the same clean backdrop; their own page
   overrides still apply if needed. */
body:has(.mw-page) {
  background: var(--white);
  min-height: 100vh;
}
/* Detail pages inherit .mw-page's horizontal gutter (--space-6 — line
   250) so the inner content lines up with /work/projects on every
   breakpoint. The listing-hero-panel on kit/program detail pages
   full-bleeds via its own negative margin (line 318), so keeping the
   gutter here doesn't push those hero bands inward. */
.mw-page--detail { padding-bottom: var(--page-padding-bottom); }

/* ─────────────────────────────────────────────────────────────
   Listing-hero band — mirrors free.css L54-94 (`.free-page
   .listing-hero` + `.free-page .listing-hero-panel`) so the /work
   heading sits in the same full-bleed panel with the same spacing
   rhythm as /free + /explore. Scoped to .mw-page so these rules do
   not leak into the home page or any other consumer.

   ⚠️ MUST-MATCH WITH free.css L66-100 (`.free-page .listing-hero`
   + `.free-page .listing-hero-panel`). The two copies exist
   (rather than a shared selector) so each page can carry its own
   scoped overrides without entangling the other consumer — but
   the BASE rules below MUST read identically. /free, /explore,
   and /work all share the same flush-heading layout (no 100px
   top push) per Christine's "massive gap" feedback (4 May 2026).

   PARITY rules (must stay identical between work.css + free.css):
     • .listing-hero — z-index, width-breakout (margin-left/right
       calc + width: 100vw), padding, overflow.
     • .listing-hero-panel — --listing-hero-bg, margin, border-radius,
       background, padding, overflow.
     • mobile @media — margin, border-radius, padding.
   ─────────────────────────────────────────────────────────────── */
.mw-page .listing-hero {
  position: relative;
  /* Break out of .mw-page (max-width 1390px) so the panel spans the
     full viewport width like /free's hero. */
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  width: 100vw;
  padding: 0;
  overflow: visible;
}
.mw-page .listing-hero-panel {
  --listing-hero-bg: transparent;
  position: relative;
  /* IDENTICAL to /free + /explore (free.css L101):
       padding: var(--listing-hero-pad-top) var(--space-8) var(--space-7);
     The token IS the value — no calc, no scoped overrides.
     For this to match /free's heading position, .page-content's
     48px top padding is structurally zeroed via the :has() rule
     below (work.css L2806 area), because /free is in base-app.html
     which has NO .page-content wrapper above its panel. */
  margin: 0 var(--space-10);
  border-radius: 0;
  background: var(--listing-hero-bg);
  padding: var(--listing-hero-pad-top) var(--space-8) var(--space-7);
  overflow: hidden;
}
@media (max-width: 768px) {
  .mw-page .listing-hero-panel {
    margin: var(--space-3) var(--space-3) 0;
    border-radius: 28px;
    padding: 60px var(--space-5) var(--space-5);
  }
}
.mw-page .page-title-block {
  /* Lives inside .listing-hero-panel — the panel provides the outer
     padding, this block just centers the text and caps the width
     so the heading doesn't span the full panel on wide monitors. */
  margin: 0 auto;
  padding: 0;
  text-align: center;
  max-width: 1200px;
}

/* Subtitle under the heading — mirrors free.css L2098-2117 so the
   /work tagline renders identically to /free + /explore. The
   .show-on-mobile / .hide-on-mobile pair toggles which fragment is
   visible at <=768px. */
.mw-page .page-title-desc {
  text-align: center;
  font-size: var(--text-base);
  /* Christine (28 May): brand black (#0f1e41) for page hero
     subheadings — pairs with .mw-page-h1 above. */
  color: var(--navy);
  margin: 0 auto;
  max-width: 720px;
  /* line-height 1.55 — matches free.css L2327 (`.free-page
     .page-title-desc { line-height: 1.55 }`). The 1.25 value
     that lived here previously was a drift from the original
     mirror: the tighter leading shifted the subhead's first line
     up so the visual gap between H1 and subhead read differently
     from /free + /explore, which Christine flagged on 26 May 2026
     ("gap is too big for My Work between the heading and
     subheading — make them the same"). Re-sync to /free. */
  line-height: 1.55;
}
.mw-page .page-title-desc strong {
  color: var(--navy);
  font-weight: var(--font-weight-semibold, 600);
}
.mw-page .page-title-desc .show-on-mobile { display: none; }
@media (max-width: 768px) {
  .mw-page .page-title-desc { font-size: var(--text-sm) !important; }
  .mw-page .page-title-desc .hide-on-mobile { display: none; }
  .mw-page .page-title-desc .show-on-mobile { display: inline; }
}

/* My Work heading — uses the same --section-heading token that
   .section-title applies on /free + /explore so the typography lines
   up across the three pages. We keep the .mw-page-h1 hook for any
   page-specific overrides but the size/weight come from the shared
   .section-title rule the element also carries. */
.mw-page-h1 {
  /* Christine (28 May): brand black (#0f1e41) for page hero
     headings — see --brand-black in tokens/colors.css. */
  color: var(--navy);
  /* No letter-spacing override — /free + /explore use natural Inter
     tracking on .page-title, so adding a -0.01em tightening here
     made the heading read denser/heavier than the other pages even
     though the resolved font-weight (semibold/600) was identical. */
  margin: 0;
  text-align: center;
}

/* Hard-override .section-title's margin-bottom (24px) when the
   heading is used inside the My Work hero. /free + /explore neutralise
   the same 24px via `.free-page .page-title { margin: 0 }` (free.css
   L2314) — their H1 carries the .page-title class. /work's H1 doesn't,
   so the .section-title margin leaks through despite .mw-page-h1's
   `margin: 0` (equal specificity → cascade order should win, but the
   gap Christine reported on 26 May 2026 between "My Work" and its
   subhead shows the override wasn't sticking). Higher specificity
   selector + explicit zero on every side guarantees the heading sits
   flush above the subhead, matching /free + /explore + /solutions. */
.mw-page .page-title-block .mw-page-h1,
.mw-page .page-title-block .section-title {
  margin: 0 !important;
}

/* (Removed 4 May 2026: the bare-h1 navbar-clearance rule that lived
   here — work_projects, work_library, and program-participant now
   render the same .listing-hero-panel structure as /work, so they
   inherit the panel's padding-top from the shared rule at L321.
   One selector, one token, no calc. Detail pages (.mw-page--detail)
   keep their own .mw-h1-row styling at the .mw-page--detail rule
   below — unaffected by this deletion.) */

/* Project-detail page (/work/p/<id>) keeps the legacy compact title
   instead of the full hero band — these pages don't render the
   .listing-hero wrapper, just a bare .mw-h1-row + .mw-page-h1. The
   rules below only fire on .mw-page--detail so the index page is
   unaffected. */
.mw-page--detail .mw-h1-row {
  display: flex;
  align-items: center;
  margin: var(--space-5) 0 0;
  padding: 0 0 10px;
  gap: var(--space-4);
  min-height: 42px;
}
/* Scoped to .mw-h1-row only — the legacy compact title used by
   project-detail (work_project.html). Pages like program-participant
   that render the full .listing-hero band must keep the centered
   hero typography from .mw-page-h1 above; this override accidentally
   left-aligned and shrank those headings before scoping. */
.mw-page--detail .mw-h1-row .mw-page-h1 {
  font-size: var(--text-2xl);
  font-weight: var(--font-weight-semibold);
  text-align: left;
}

.mw-newchat-btn {
  /* Christine (28 May): match the home page hero CTA pill exactly
     (.landing-hero-btn, home.css L619-632): fully-rounded 100px
     pill, 19px/28px padding, 16px/600 type, 10px icon gap,
     `--black` fill. Was a smaller 12px-radius rectangle.
     `--black` (#0f1e41) is the brand dark-navy token in
     tokens/colors.css, used here for the pill fill. */
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 19px 28px;
  border-radius: 100px;
  background: var(--navy);
  color: var(--white);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  line-height: 1;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.25s ease, color 0.25s ease, transform 0.25s ease, border-color 0.25s ease;
}
.mw-newchat-btn:hover {
  /* Christine (28 May): hover to brand --pink (#FF00AA) to mirror
     the home page's navbar Get Started pill hover treatment. Was
     a simple opacity dim; the pink flip makes the primary CTA
     feel actively branded on interaction. */
  background: var(--pink);
  color: var(--white);
  opacity: 1;
}
@media (max-width: 768px) {
  .mw-newchat-btn {
    padding: 10px var(--space-3);
    font-size: var(--text-sm);
  }
}

/* Search bar — uses home-page classes (activity-search-bar + home-search-bar--hero
   + home-search-btn-pill). Local rules below only set the wrapping form element
   and a leading search icon; everything else inherits from the home tokens. */
.mw-search-form {
  /* The outer form matches the 1342px container used by /free +
     /explore (.page-search-bar-inner). Symmetric 5% padding on
     each side reproduces the same ~67px side margin that
     .free-search-pill gets from its width: 90%; margin: 0 auto.
     Padding (not width on the inner bar) is used because the
     inner bar inherits flex: 1 1 auto from home-search.css and
     would override any width set directly on it.
     Top margin reduced from 24px → 4px on 4 May 2026 per Christine
     ("gap before the search bar is quite large, reduce 20px").
     Mirrors free.css L154-159 — keep in sync. */
  margin: var(--space-1) auto var(--space-2);
  width: 100%;
  max-width: 1342px;
  padding-left: 5%;
  padding-right: 5%;
  box-sizing: border-box;
}
@media (max-width: 768px) {
  .mw-search-form {
    padding-left: 0;
    padding-right: 0;
  }
  .mw-search-form .free-search-input::placeholder { color: var(--gray-mid); }
  /* Hide text "Clear results" — replaced by in-pill × button on mobile */
  .mw-page .clear-results-link { display: none !important; }
  /* Show FILES + PROJECTS tabs on mobile — Resources, star and New Chat hidden */
  .mw-page .free-tabs-row.mw-tabs-row {
    display: flex;
    padding: 0 !important;
    margin-top: calc(var(--space-4) + 10px);
    margin-bottom: 18px;
  }
  .mw-page .free-tabs-row.mw-tabs-row .home-mega-bar { gap: 12px; }
  /* Hide star tab */
  .mw-page .free-tabs-row.mw-tabs-row .home-mega-tab:has(> .mw-tab-starred--icon-only) { display: none; }
  /* Hide New Chat button in the strip */
  .mw-page .free-tabs-row.mw-tabs-row .mw-newchat-btn--inline { display: none; }
  /* Tab labels — all cyan, bold, uppercase */
  .mw-page .free-tabs-row.mw-tabs-row .home-mega-trigger {
    color: var(--cyan) !important;
    text-transform: uppercase;
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.05em;
    padding: 6px 0;
    text-decoration: none;
  }
  /* Active tab: cyan underline */
  .mw-page .free-tabs-row.mw-tabs-row .home-mega-trigger.active {
    text-decoration: underline;
    text-underline-offset: 4px;
    text-decoration-thickness: 2px;
  }
  /* Suppress default ::after indicator */
  .mw-page .free-tabs-row.mw-tabs-row .home-mega-trigger::after,
  .mw-page .free-tabs-row.mw-tabs-row .home-mega-trigger.active::after { display: none; }
  /* ---- /work/projects + /program tab strip (.mw-pills-row--with-actions) ---- */
  .mw-page .mw-pills-row--with-actions {
    padding: 0 !important;
    margin-top: calc(var(--space-4) + 10px);
    margin-bottom: 18px;
  }
  .mw-page .mw-pills-row--with-actions .home-search-row-inner { flex: 1; }
  .mw-page .mw-pills-row--with-actions .home-mega-bar { gap: 12px; }
  /* Hide sort/actions on mobile */
  .mw-page .mw-pills-row--with-actions .mw-pills-actions { display: none; }
  /* Hide star tab */
  .mw-page .mw-pills-row--with-actions .home-mega-tab:has(> .mw-tab-starred--icon-only) { display: none; }
  /* Tab labels — all cyan, bold, uppercase */
  .mw-page .mw-pills-row--with-actions .home-mega-trigger {
    color: var(--cyan) !important;
    text-transform: uppercase;
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.05em;
    padding: 6px 0;
    text-decoration: none;
  }
  /* Active tab: cyan underline */
  .mw-page .mw-pills-row--with-actions .home-mega-trigger.active {
    text-decoration: underline;
    text-underline-offset: 4px;
    text-decoration-thickness: 2px;
  }
  /* Suppress default ::after indicator */
  .mw-page .mw-pills-row--with-actions .home-mega-trigger::after,
  .mw-page .mw-pills-row--with-actions .home-mega-trigger.active::after { display: none; }

  /* Hide the ALL FILES section heading — tabs replace it */
  .mw-page .home-list-col .all-reports-heading { display: none !important; }
  /* Hide the entire info row on mobile */
  .mw-page .mw-info-row { display: none; }
  /* Collapse the spacer that compensated for the hidden tabs */
  .mw-allfiles-spacer { display: none; }
  /* Expanded file meta — mobile simplifications */
  /* "Report ID:" → "#" */
  #pm-report-id-row .mw-pmeta-label { font-size: 0; }
  #pm-report-id-row .mw-pmeta-label::after { content: '#'; font-size: var(--text-sm); }
  /* Hide Category and Product rows */
  #pm-category-row,
  #pm-product-row { display: none !important; }
  /* Status: hide the text label — dot + value in the badge remain */
  #pm-status-row .mw-pmeta-label { display: none; }
}
/* Filter icon: hidden on desktop, shown inside pill on mobile via free.css */
.mw-page .mw-search-filter-btn { display: none; }
@media (max-width: 768px) {
  .mw-page .mw-search-filter-btn { display: flex; }
}

.mw-pd .mw-search-form .activity-search-bar {
  min-height: 150px;
  border-color: var(--gray-light);
  background: var(--white);
  align-items: flex-start;
  padding-top: calc(var(--space-4) + 10px);
  position: relative;
}
/* Clear (×) button inside Projects + Programs search bars */
.mw-proj-search-clear {
  display: none;
  flex: 0 0 auto;
  appearance: none;
  background: var(--gray-mid);
  border: none;
  width: 18px; height: 18px;
  border-radius: var(--radius-full);
  align-items: center; justify-content: center;
  color: #ffffff;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  margin-right: var(--space-1);
  transition: background 0.15s ease;
}
.mw-proj-search-clear.visible { display: inline-flex; }
.mw-proj-search-clear:hover { background: var(--ink-2); }

/* Project-detail (work_project.html) no longer hosts the in-page chat
   composer — the search bar is now a plain search input that mirrors
   the /work Files page. The .mw-pd block above was sized for the old
   tall composer (150px); reset it back to the standard hero search-bar
   dimensions on .mw-page--detail so the bar reads at 68px. work_kit.html
   still has the composer (different template) and is unaffected.
   Specificity 0,4,1 wins over the 0,3,1 .mw-pd rule above. */
.mw-page--detail .mw-pd .mw-search-form .activity-search-bar {
  min-height: 0;
  height: 58px;
  align-items: center;
  padding-top: 0;
  border-radius: var(--ew-search-radius);
}
/* Detail-page search form fills the .mw-pd left column edge-to-edge.
   The base .mw-search-form has 5% side padding (mirrors /free + /explore
   hero); we strip it here so the bar reads as 100% column width. */
.mw-page--detail .mw-pd .mw-search-form {
  padding-left: 0;
  padding-right: 0;
  max-width: none;
}
/* Right-align the "+ New chat" button inside the .mw-pd left column.
   The .free-tabs-row default flex+space-between handles alignment;
   we just need a small vertical rhythm above the select_row below. */
.mw-pd .mw-pd-newchat-row {
  width: 100%;
  margin: var(--space-3) 0 var(--space-2);
}

/* Project-detail variant: search bar + "+ New chat" share one row.
   The form is already display:flex (home-search.css). We add a gap
   and let the search bar grow while the action button keeps its
   intrinsic width on the right. The 5% side padding on .mw-search-form
   is dropped here so the row spans the full left-column width. */
.mw-pd .mw-search-form--with-action {
  padding-left: 0;
  padding-right: 0;
  gap: var(--space-3);
  align-items: center;
}
/* Project-detail: breathing room above the file list. */
.mw-pd .home-popular-list {
  margin-top: 30px;
}
/* Project-detail: align the select-row's "N files / Select" text with
   the file-row text below (which sits 18px in from the column edge via
   .mw-frow's padding). The global .mw-info-row uses --space-10 (40px)
   left padding for the listing pages — narrow it here. */
.mw-pd .mw-info-row {
  padding-left: 18px;
}
.mw-pd .mw-search-form--with-action .activity-search-bar {
  flex: 1 1 auto;
  min-width: 0;
  /* Override the 68px hero height (.home-search-bar--hero) for the
     project-detail variant — slimmer 58px bar to match the action
     button alongside it. */
  height: 58px;
}
.mw-pd .mw-search-form-action {
  flex: 0 0 auto;
  white-space: nowrap;
  /* Match the search bar height exactly. Use height (not padding) so
     both flex children align on the same baseline regardless of font
     metrics. */
  height: 58px;
  padding-top: 0;
  padding-bottom: 0;
}
/* Fully-rounded pill variant — matches the search bar's pill radius
   (--ew-search-radius = --radius-full = 999px). */
.mw-pd .mw-search-form-action--pill {
  border-radius: var(--radius-full);
  padding-left: var(--space-5);
  padding-right: var(--space-5);
}
.mw-attach-btn {
  width: 32px;
  height: 32px;
  border: none;
  background: transparent;
  color: var(--navy);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.mw-attach-status {
  margin-left: 10px;
  font-size: 12px;
  color: var(--gray-500);
  font-weight: 300;
}
.mw-attach-status.ok { color: var(--navy); }
.mw-attach-status.err { color: #d00; }
.mw-pd .mw-search-form .activity-search-input {
  color: var(--navy);
  font-weight: 400;
}
.mw-pd .mw-search-form .activity-search-input::placeholder {
  color: var(--gray-mid);
  font-weight: 400;
}
.mw-chat { margin: 40px 0; }
/* The wrapping <form> uses .mw-search-form, which is set to display:flex
   in home-search.css. Without a flex-grow rule the chat-card shrinks to
   its content (~190px) and looks squished. Mirror the rule that
   home-search.css applies to .activity-search-bar so the composer fills
   the column instead. */
.mw-search-form > .mw-chat-card {
  flex: 1 1 auto;
  min-width: 0;
}
.mw-chat-card {
  display: flex; flex-direction: column;
  background: var(--white);
  border: 1px solid var(--gray-light);
  border-radius: 16px;
  padding: var(--space-4) var(--space-5);
  gap: var(--space-3);
  min-height: 150px;
  /* Drop shadow lifts the chat composer above the flat right-column
     panels so it reads as the primary action on the page rather than
     blending in with the Memory / Instructions / Files panels. */
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.04);
}
.mw-chat-messages {
  display: flex; flex-direction: column; gap: var(--space-3);
  max-height: 480px; overflow-y: auto;
}
.mw-chat-messages:empty { display: none; }
.mw-chat-msg {
  font-size: 15px;
  line-height: 1.5;
  color: var(--navy);
  font-weight: 400;
  word-wrap: break-word;
  max-width: 90%;
}
.mw-chat-msg--user {
  align-self: flex-end;
  background: var(--gray-background);
  padding: var(--space-3) var(--space-5);
  border-radius: 20px;
  width: fit-content;
}
.mw-chat-msg--assistant {
  align-self: flex-start;
  background: transparent;
  padding: var(--space-2) 0;
  line-height: 1.6;
}
.mw-chat-msg.pending { color: var(--gray-mid); font-style: italic; }
.mw-chat-msg.err { color: #d00; }
.mw-chat-msg a { color: var(--navy); text-decoration: underline; }
.mw-chat-textarea {
  resize: none;
  overflow-y: auto;
  min-height: 24px;
  max-height: 280px;
  line-height: 1.4;
  font-size: 15px;
  font-family: inherit;
  font-weight: 400;
  color: var(--navy);
  border: none;
  outline: none;
  background: transparent;
  width: 100%;
  padding: var(--space-1-5) var(--space-2);
  display: block;
}
.mw-chat-textarea::placeholder { color: var(--gray-mid); font-weight: 400; }
.mw-chat-bar {
  position: relative;
  display: flex; align-items: center; justify-content: flex-end;
  min-height: 32px;
  margin-top: auto;
}
.mw-search-form .mw-search-icon {
  display: flex;
  align-items: center;
  color: var(--gray-mid);
  flex-shrink: 0;
  padding-right: var(--space-1);
}
.mw-search-form .mw-search-icon svg {
  width: 19px; height: 19px;
  stroke: currentColor; fill: none; stroke-width: 1.8;
}

/* Tabs row: home-page mega-trigger style (uppercase, transparent, left-aligned).
   Everything (H1, FILES tab, info row) aligns to the page left edge.
   These rules still apply on /work/projects, /work/library, and
   /program-participant, which keep the .home-pills-row wrapper. The
   /work index has been migrated to .free-tabs-row (block below). */
.mw-page .home-pills-row {
  margin: var(--space-1) auto var(--space-2);
  /* Shift the tab bar right so the first tab's text lines up with
     the row title column below (40px from container = 16px row
     margin + 24px row padding-left). Tabs add their own 10px of
     padding-left, so 30px here puts the label at 40px. */
  padding: 0 0 0 var(--space-7-5);
  width: 1310px;
  max-width: 1310px;
}
/* Tabs row is a flex container so "+ New Chat" can sit right-aligned
   on the same line as the FILES/PROJECTS/PROGRAM/KITS tabs. The
   parent rule in home-search.css sets flex-direction: column on
   .home-search-row-inner — we explicitly switch back to row here so
   the button stays on the same line as the tabs instead of wrapping
   below them. */
.mw-page .home-pills-row .home-search-row-inner {
  padding: 0;
  width: 100%;
  max-width: 1310px;
  margin: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
/* Right-aligned variant of the New Chat button when it lives in
   the tabs row instead of the heading row. Keeps the same pill
   styling but trims the vertical padding so it matches the tab
   strip's height. */
.mw-page .home-pills-row .mw-newchat-btn--inline {
  flex: 0 0 auto;
  margin-right: var(--space-7-5);
}

/* /work index tabs row — mirrors free.css L214-227 .free-tabs-row so
   the wrapper margins and flex behaviour line up with /free +
   /explore (20px top / 4px bottom, flex-end alignment so the
   New Chat button bottom-aligns with the tab underline). The
   .mw-tabs-row hook scopes the /work-only width + left padding
   overrides without leaking into .free-page consumers. The
   .free-tabs-row rules in free.css are scoped to .free-page so they
   don't reach this template — same duplication pattern we use for
   .listing-hero and .page-title-desc. */
.mw-page .free-tabs-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6);
  margin: var(--space-5) auto var(--space-1);
  background: transparent;
}
.mw-page .free-tabs-row.mw-tabs-row {
  /* Match /free + /explore exactly: 1342px wide (same as the search
     pill above and .page-search-bar-inner on /free), with symmetric
     40px (--space-10) side gutters so the first tab label (FILES)
     sits at the same x as the heading inside .listing-hero-panel.
     Top margin matches /free's .free-tabs-row (.free-page L283:
     `margin: var(--space-5) 0 var(--space-1)`) — the +space-7
     override that used to live here added 8px of extra gap above
     the tabs strip on /work only. Christine asked for /work to
     match /free + /explore — both vertically and horizontally. */
  width: 1342px;
  max-width: 1342px;
  /* Christine (28 May): dropped right gutter to 0 so trailing
     controls (e.g. the New Chat button) sit flush with the search
     pill's right edge. Left gutter stays at --space-10 (40px). */
  padding: 0 0 0 var(--space-10);
  /* margin-top inherited from .mw-page .free-tabs-row above
     (var(--space-5) = 20px) — same as /free. */
}
.mw-page .free-tabs-row .home-mega-bar { flex: 1 1 auto; min-width: 0; }
.mw-page .free-tabs-row .mw-newchat-btn--inline {
  flex: 0 0 auto;
  /* Right padding on .mw-tabs-row already handles the gutter — no
     extra margin needed (the .home-pills-row variant above keeps
     its 30px because that wrapper has no right padding). */
  margin-right: 0;
}
/* Tab strip typography + spacing tokenized to match /free's
   .free-tab look (free.css L301-334) so the FILES/PROJECTS/PROGRAM/
   KITS row reads the same as ALL/MARKET/COUNTRY on /free and
   ALL/RESEARCH/PLANNING/… on /explore:
     - gap 28px between tabs (was var(--space-1) = 4px → too tight)
     - padding 10px 0 (was 8px 10px → row was 34px tall vs /free's 41)
     - letter-spacing 0.06em (was 0 → labels read tighter than /free)
     - inactive color var(--ink-2) (was inherited black →
       no contrast between active and inactive)
   The ::after underline implementation is kept (vs /free's
   box-shadow inset) — visually identical, less risk of regression. */
.mw-page .home-mega-bar { gap: 28px; max-width: 1342px; }
.mw-page .home-filter-bar--hero .home-mega-trigger {
  position: relative;
  text-decoration: none;
  border: none;
  border-radius: 0;
  padding: 10px 0;
  font-size: var(--caption);
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--ink-2);
}
.mw-page .home-filter-bar--hero .home-mega-trigger.active { font-weight: 700; }
.mw-page .home-filter-bar--hero .home-mega-trigger::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: transparent;
}
.mw-page .home-filter-bar--hero .home-mega-trigger:hover { color: var(--text-primary); }
.mw-page .home-filter-bar--hero .home-mega-trigger.active { color: var(--text-primary); }
.mw-page .home-filter-bar--hero .home-mega-trigger.active::after { background: var(--text-primary); }

/* ============================================================
   Projects tab — grid of project cards (work_projects.html).
   ============================================================ */

.mw-projbar {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  width: 1360px;
  max-width: 1360px;
  margin-left: calc((100% - 1400px) / 2 + 10px);
  margin-right: auto;
  padding: 0 var(--space-6) var(--space-3) 47px;
  box-sizing: border-box;
  font-size: var(--text-sm);
  color: var(--gray-mid);
}

/* Right-aligned actions on the tabs row (Show archived + Sort by).
   Spacing tuned for /work/projects, /program, /work/library:
   28px top breathing room from the search bar, no horizontal margin
   so the row sits flush with the page gutter, and 40px L/R padding
   pushes the tabs + action buttons inward from the panel edge.

   Selector is double-classed (.mw-page + .mw-pills-row--with-actions)
   to outrank the base .mw-page .home-pills-row rule at L599 which
   sets margin: 4px 16px 8px and padding: 0 0 0 30px. Without the
   .mw-page prefix our rule has the same specificity and source
   order doesn't help (L599 comes first but they tie on specificity
   so the second declaration wins ONLY for properties they both
   set — but the L599 shorthand and our longhand both touch margin,
   making the cascade brittle). Explicit higher specificity is the
   safe fix. */
.mw-page .mw-pills-row--with-actions {
  display: flex;
  align-items: center;
  margin: 28px 0 var(--space-2);
  padding: 0 0 0 40px;
}
.mw-pills-row--with-actions .home-search-row-inner {
  flex: 1 1 auto;
  min-width: 0;
}
.mw-pills-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-right: var(--space-2);
  flex-shrink: 0;
  margin-left: auto;
}
/* Tighten the "+ New Project" button when it sits inside the
   pills-actions cluster:
     • margin-right: 0   — drops the 30px from the base
                           .mw-page .home-pills-row .mw-newchat-btn--inline
                           rule (L632) so spacing to the Sort by
                           dropdown comes only from the container's
                           own --space-2 (8px) flex gap.
     • padding-right: 10px — asymmetric pill (left stays at the base
                             18px; only the right tightens per
                             Christine's 4 May 2026 request).
   Selector is .mw-page-prefixed to tie specificity (0,3,0) with the
   L632 rule above so margin-right: 0 actually applies. */
.mw-page .mw-pills-actions .mw-newchat-btn--inline {
  margin-right: 0;
  padding-right: 10px;
}
/* Hide the Sort-by + Show-archived controls on phones — they
   crowd the pills row and aren't worth the space at this width.
   Desktop view is unchanged. */
@media (max-width: 768px) {
  .mw-pills-actions { display: none; }
}
.mw-projbar-left { flex: 1 1 auto; min-width: 0; }

.mw-projarch-toggle {
  background: none;
  border: 0;
  padding: var(--space-1) var(--space-1-5);
  margin: 0;
  font-family: inherit;
  font-size: var(--text-xs);
  color: var(--gray-mid);
  cursor: pointer;
  border-radius: var(--radius-sm, 6px);
  transition: color 120ms ease;
}
.mw-projarch-toggle:hover { color: var(--navy); }
.mw-projarch-toggle[aria-pressed="true"] { color: var(--navy); font-weight: var(--font-weight-medium); }

/* ---------------------------------------------------------------- */
/* Sort A-Z toggle — small icon button that lives in .mw-info-default
   right after the "Select" link. Same colour rhythm as
   .mw-projarch-toggle (idle grey-mid → hover/active black) so it
   visually pairs with the rest of the info-row controls. Square
   24×24 hit target keeps it easy to tap on touch devices while
   staying flush with the baseline-aligned text siblings. */
/* ---------------------------------------------------------------- */
.mw-sort-toggle {
  background: none;
  border: 0;
  padding: 0;
  margin: 0 0 0 var(--space-1-5);
  width: 24px;
  height: 24px;
  /* inline-flex !important to defeat the
       .mw-info-row .mw-info-default > * { display: inline-block; }
     rule above, which would otherwise reset the button's display
     and break the inner svg centring. */
  display: inline-flex !important;
  align-items: flex-end;
  justify-content: center;
  color: var(--gray-mid);
  cursor: pointer;
  border-radius: var(--radius-sm, 6px);
  transition: color 120ms ease, background-color 120ms ease;
  /* Align the icon-button to the "Select" text baseline (Christine,
     28 May) — the bottom of the A/Z letters in the glyph sits on
     the same baseline as the surrounding text. The flex-end above
     pins the 18px SVG to the bottom of the 24px button box so the
     glyph reads as bottom-aligned with the adjacent text rather
     than floating above it. */
  vertical-align: baseline;
}
.mw-sort-toggle svg { width: 18px; height: 18px; display: block; }
.mw-sort-toggle:hover { color: var(--navy); }
.mw-sort-toggle.is-active,
.mw-sort-toggle[aria-pressed="true"] { color: var(--navy); }
/* Three-state sort cycle visual: arrow rotates to show direction.
   none (default): arrow points down (will sort A-Z next).
   asc:  arrow points down — currently sorted A-Z.
   desc: arrow flips up — currently sorted Z-A; letters also swap
         (Z on top, A on bottom) so the glyph reads as Z↑A. */
.mw-sort-toggle .mw-sort-arrow {
  transform-origin: 16px 12px;
  transition: transform 150ms ease;
}
.mw-sort-toggle[data-sort-state="desc"] .mw-sort-arrow {
  transform: rotate(180deg);
}
/* Swap A/Z visually in the desc state. SVG <text> doesn't accept
   ::before content swaps — so instead we translate each letter by
   the 10-unit baseline gap, which places Z on top and A on bottom
   without flipping the glyphs themselves. */
.mw-sort-toggle .mw-sort-letter-top,
.mw-sort-toggle .mw-sort-letter-bottom {
  transition: transform 150ms ease;
}
.mw-sort-toggle[data-sort-state="desc"] .mw-sort-letter-top {
  transform: translateY(10px);
}
.mw-sort-toggle[data-sort-state="desc"] .mw-sort-letter-bottom {
  transform: translateY(-10px);
}

.mw-projsort {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-8) 0 var(--space-4);
  min-height: 40px;
  border: 1px solid var(--gray-light);
  border-radius: var(--radius-md);
  background: var(--white);
  color: var(--ink-2);
  font-size: var(--text-sm);
  font-family: inherit;
  cursor: pointer;
  transition: border-color 120ms ease, color 120ms ease;
}
.mw-projsort:hover { border-color: var(--navy); color: var(--navy); }
.mw-projsort-label { color: var(--gray-mid); }
/* Native select sits invisibly over the label so only "Sort by" + caret show,
   while the full control remains clickable to open the system menu. */
.mw-projsort-select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: transparent;
  cursor: pointer;
  outline: none;
  opacity: 0;
}
.mw-projsort-caret {
  position: absolute;
  right: 10px;
  top: 50%;
  width: 14px;
  height: 14px;
  transform: translateY(-50%);
  pointer-events: none;
  color: currentColor;
}

.mw-projgrid {
  display: grid;
  /* 2-up on desktop (matches Claude's projects layout). The mobile
     breakpoint below collapses to a single column and zeros the L/R
     padding because .mw-page's own 24px page gutter is enough on
     phones — adding 40px on top would crush the single-column card. */
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
  margin-top: 60px;
  padding: 0 var(--space-10);
  box-sizing: border-box;
}
@media (max-width: 768px) {
  .mw-projgrid {
    grid-template-columns: 1fr;  /* one card per row on phones */
    gap: var(--space-3);
    margin-top: var(--space-6);
    padding: 0;
  }
}
.mw-projcard {
  position: relative;
  background: var(--white);
  border-radius: var(--radius-lg);
  height: 160px;
  box-shadow: var(--ew-preview-section-shadow);
  transition: box-shadow 0.1s, transform 0.1s;
}
.mw-projcard.is-locked {
  background: var(--bg-secondary);
  cursor: not-allowed;
  opacity: 0.85;
}
.mw-projcard.is-locked .mw-projcard-link {
  cursor: not-allowed;
}
.mw-projcard.is-locked .mw-projcard-name {
  color: var(--gray-mid);
}
.mw-projcard-link {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--space-2);
  height: 100%;
  padding: 18px var(--space-5);
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
.mw-projcard-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-right: var(--space-8);
}
.mw-projcard-name {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--navy);
}
.mw-projcard-badge {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px var(--space-2);
  border-radius: var(--radius-full, 999px);
  font-weight: var(--font-weight-semibold);
}
.mw-projcard-badge.kit {
  background: color-mix(in srgb, var(--cyan) 18%, var(--white));
  color: color-mix(in srgb, var(--cyan) 75%, var(--navy));
}
.mw-projcard-badge.program { background: var(--white); color: var(--ink-2); border: 0.75px solid var(--gray-light); }
.mw-projcard-badge.manual { background: var(--gray-light); color: var(--ink-2); }
.mw-projcard-desc {
  margin-top: 0;
  font-size: var(--text-sm);
  color: var(--ink-2);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-word;
}
.mw-projcard-meta {
  margin-top: auto;
  font-size: var(--text-xs);
  color: var(--gray-mid);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.mw-projcard-meta-dot {
  font-size: var(--text-xs);
  line-height: 1;
  color: var(--gray-mid);
  opacity: 0.7;
}

/* Per-card pin toggle: hover-revealed; always visible when pinned (mirrors .mw-frow-star) */
.mw-projcard-pin {
  position: absolute;
  top: var(--space-3);
  right: 44px;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  padding: 0;
  border-radius: var(--radius-sm);
  color: var(--gray-mid);
  cursor: pointer;
  z-index: 2;
  opacity: 0;
  visibility: hidden;
  transition: opacity 120ms ease, color 120ms ease;
}
.mw-projcard-pin svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.6;
}
.mw-projcard:hover .mw-projcard-pin {
  opacity: 1;
  visibility: visible;
}
.mw-projcard-pin:hover { color: var(--navy); }
.mw-projcard-pin.is-pinned {
  opacity: 1;
  visibility: visible;
  color: var(--navy);
}
.mw-projcard-pin.is-pinned svg { fill: var(--navy); }

/* 3-dot menu button */
.mw-projcard-menu-btn {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--gray-mid);
  cursor: pointer;
  padding: 0;
  z-index: 2;
}
.mw-projcard-menu-btn:hover {
  background: var(--bg-hover);
  color: var(--navy);
}

/* ===== Bulk-select on the Projects tab =====
   Mirrors the Files tab pattern: a per-card checkbox revealed by
   .mw-page.is-selecting, plus a "selected" treatment on the card. */
.mw-projcard-check {
  position: absolute;
  /* Sits in the top-right action cluster, just LEFT of the pin button.
     Slot math mirrors the existing pin/menu pattern at L916/L957:
       menu  right: 12 (--space-3) + 28 wide → spans right 12-40
       pin   right: 44             + 28 wide → spans right 44-72  (4px gap to menu)
       check right: 76             + 16 wide → spans right 76-92  (4px gap to pin)
     The 16px box is vertically centered against the 28px pin/menu
     buttons via top = 12 + (28-16)/2 = 18px = --space-4-5. */
  top: var(--space-4-5);
  right: 76px;
  width: var(--space-4);
  height: var(--space-4);
  margin: 0;
  padding: 0;
  cursor: pointer;
  z-index: 3;
  -webkit-appearance: none;
  appearance: none;
  background: var(--white);
  border: 1.5px solid var(--gray-mid);
  border-radius: 3px;
  display: none;
}
.mw-page.is-selecting .mw-projcard-check { display: block; }
.mw-projcard-check:checked {
  background: transparent;
  border-color: var(--navy);
}
.mw-projcard-check:checked::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--space-1);
  height: var(--space-2);
  border: solid var(--navy);
  border-width: 0 1.5px 1.5px 0;
  transform: translate(-50%, -65%) rotate(45deg);
}

/* Selected card visual treatment + a subtle pointer hint while selecting. */
.mw-projcard.selected {
  border-color: var(--navy);
  background: var(--bg-hover);
}
.mw-page.is-selecting .mw-projcard { cursor: pointer; }
.mw-page.is-selecting .mw-projcard .mw-projcard-link { pointer-events: none; }

/* Toolbar row positioning: the "Select" link + selecting toolbar above the grid. */
.mw-projsel-row {
  margin-bottom: var(--space-3);
}
.mw-projsel-allwrap {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding-left: var(--space-5);
  position: relative;
}
.mw-projsel-allwrap .mw-select-all-box {
  position: static;
  transform: none;
  left: auto;
  top: auto;
  opacity: 1;
  visibility: visible;
}

/* Dropdown menu (one per card, absolutely positioned in card) */
.mw-projmenu {
  position: absolute;
  top: 44px;
  right: var(--space-3);
  z-index: 9000;
  min-width: 200px;
  background: var(--white);
  border: 1px solid var(--gray-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: var(--space-2);
  display: none;
}
.mw-projmenu.open { display: block; }
.mw-projmenu-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0;
  background: transparent;
  font-size: var(--text-sm);
  color: var(--navy);
  text-align: left;
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.mw-projmenu-item:hover { background: var(--bg-hover); }
.mw-projmenu-item svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--gray-mid); }
.mw-projmenu-item.is-danger { color: var(--negative); }
.mw-projmenu-item.is-danger svg { color: var(--negative); }
.mw-projmenu-divider {
  height: 1px;
  background: var(--gray-light);
  margin: var(--space-2) var(--space-2);
}

/* Edit-details modal */
.mw-modal-overlay {
  position: fixed;
  inset: 0;
  background: var(--overlay-bg);
  z-index: 9100;
  display: none;
  align-items: center;
  justify-content: center;
}
.mw-modal-overlay.open { display: flex; }
.mw-modal {
  background: var(--white);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  width: 560px;
  max-width: 92vw;
  box-shadow: var(--shadow-xl);
}
.mw-modal-title {
  font-size: var(--text-xl);
  font-weight: var(--font-weight-semibold);
  margin: 0 0 var(--space-5) 0;
  color: var(--navy);
}
.mw-modal-field { margin-bottom: var(--space-4); }
.mw-modal-label {
  display: block;
  font-size: var(--text-sm);
  color: var(--ink-2);
  margin-bottom: var(--space-2);
}
.mw-modal-required { color: var(--negative); }
.mw-modal-input,
.mw-modal-textarea {
  width: 100%;
  border: 1px solid var(--gray-light);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  font-family: inherit;
  color: var(--navy);
  background: var(--white);
  box-sizing: border-box;
}
.mw-modal-input:focus,
.mw-modal-textarea:focus {
  outline: none;
  border-color: var(--ink-2);
}
.mw-modal-textarea { min-height: 180px; resize: vertical; }
.mw-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-5);
}
.mw-modal-btn {
  /* Christine (28 May): radius bumped to --radius-lg (12px) so
     the modal Save/Cancel buttons match the home hero search-pill
     and the .mw-newchat-btn primary CTA across /work. */
  border-radius: var(--radius-lg);
  padding: var(--space-2) var(--space-5);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  font-family: inherit;
  min-height: var(--ta-cta-min-height, 40px);
}
.mw-modal-btn--cancel {
  background: var(--white);
  color: var(--navy);
  border: 1px solid var(--gray-light);
}
.mw-modal-btn--cancel:hover { border-color: var(--navy); }
.mw-modal-btn--save {
  background: var(--navy);
  color: var(--white);
  border: 1px solid var(--navy);
}
.mw-modal-btn--save:hover { opacity: 0.9; }

.credits-cell-link {
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
  color: inherit;
}
.credits-cell-link:hover { color: var(--navy); }

.mw-projects-empty {
  padding: var(--space-12) var(--space-6);
  text-align: center;
  color: var(--gray-mid);
  font-size: var(--text-sm);
  border: 1px dashed var(--gray-light);
  border-radius: var(--radius-lg);
  margin-top: var(--space-3);
}
.mw-projects-empty a {
  color: var(--text-brand);
  text-decoration: none;
  font-weight: var(--font-weight-medium);
}



/* ============================================================
   Files tab (work.html) — moved from inline <style> so styles
   persist across AJAX tab swaps. Tokenized.
   ============================================================ */

/* Container fitments for the home-cards used by My Work.
   Top padding zeroed (4 May 2026 per Christine) so the cards
   container sits flush below the tabs strip — was 12px top, now 0.
   Bottom padding kept at var(--space-3) for breathing room before
   the page edge. */
.mw-page .home-cards-container {
  max-width: 100%;
  padding: 0 0 var(--space-3);
  box-shadow: none;
  max-height: none;
}
/* Top padding zeroed (4 May 2026 per Christine) so the search
   section sits flush below the hero panel — was inheriting
   var(--space-6) (24px) from home-search.css L335. The
   home-search.css default still applies on /home + non-/work
   pages because this override is scoped to .mw-page. */
.mw-page .home-search-section {
  margin-left: auto;
  margin-right: auto;
  padding-top: 0;
  padding-right: 0;
  box-sizing: border-box;
}
@media (min-width: 769px) {
  .mw-page .home-search-section {
    /* Match /free + /explore content width (1342px) so the file list
       panel below the tabs sits at the same width as the tabs row
       and the search pill above — Christine asked for /work's panel
       widths to match the other listing pages. */
    width: 1342px;
    max-width: 1342px;
  }
}

/* ─────────────────────────────────────────────────────────────
   /work INDEX scaling parity with /free + /explore
   ─────────────────────────────────────────────────────────────
   Pages that carry the .listing-hero hero band (the /work index
   today; /free + /explore on the public side) share the same
   fluid scaling system: the activity column band fills its parent
   up to var(--content-max-width) (1425px) and the inner two-column
   grid uses a percentage-based right-column track so both panels
   resize together as the viewport changes — no step-jump at the
   1024px breakpoint.

   /work pages WITHOUT a listing-hero (/work/projects,
   /work/library, /program-participant) keep the legacy 1310px
   wrapper and fixed-524px right column unchanged — those layouts
   weren't migrated to the hero pattern and shouldn't shift here.

   All values pull from the existing token system:
     - var(--content-max-width)  → 1425px (cap)
     - var(--space-10)           → 40px   (horizontal gutter)
   ─────────────────────────────────────────────────────────────── */
.mw-page:has(> .listing-hero, > #mw-tab-content > .listing-hero) .home-search-section {
  /* Undo the 1310px lock applied above so the section fills its
     parent and the inner .home-cards-container takes over as the
     centering/capping element (mirrors free.css L690-694). */
  width: auto;
  max-width: none;
}
.mw-page:has(> .listing-hero, > #mw-tab-content > .listing-hero) .home-cards-container {
  /* Cap at 1342px (matches /free + /explore content width — the
     same value used by .page-search-bar-inner and .free-hero-search
     in free.css L160 + L183) so the cards panel reads at the
     identical width as the tabs strip above and the search pill,
     and as the panels on /free and /explore. Christine asked for
     /work to match those pages. Side padding stays at 0 — the row
     gutters live on .mw-info-row / .mw-tabs-row. */
  max-width: 1342px;
}
.mw-page:has(> .listing-hero, > #mw-tab-content > .listing-hero) .free-tabs-row.mw-tabs-row {
  /* Same 1342px width as the cards container above and as
     /free + /explore. Symmetric 40px gutters keep FILES / PROJECTS /
     STARRED aligned with the row content below at every viewport. */
  width: 100%;
  max-width: 1342px;
  padding: 0 var(--space-10);
}
.mw-page:has(> .listing-hero, > #mw-tab-content > .listing-hero) .home-mega-bar {
  /* The mega-bar's 1310px clamp inside the tabs row would re-pin
     the tab strip even after the wrapper is unlocked above —
     drop it so the strip flows fluid up to its parent's cap. */
  max-width: none;
}
.mw-page:has(> .listing-hero, > #mw-tab-content > .listing-hero) .mw-info-row {
  /* Match the activity band's cap so "N files" + select controls
     scale with the rows beneath them. Padding stays asymmetric
     (40px left only) — it aligns the count text with the row
     title column below; right-edge icons sit at the container
     edge, same as on /free + /explore. */
  max-width: var(--content-max-width);
}
@media (min-width: 768px) {
  .mw-page:has(> .listing-hero, > #mw-tab-content > .listing-hero) .home-activity-page .activity-columns {
    /* Match /free + /explore exactly: 55% list / 45% preview track
       (free.css L702-704: `minmax(360px, 45%)`). Christine asked
       for the preview to be 45% — same value as the other listing
       pages, so /work now reads with the same column proportions
       as /free + /explore. */
    grid-template-columns: minmax(0, 1fr) minmax(360px, 45%);
  }
}

/* File rows: flush, no per-side borders, single 0.75px hairline divider */
.mw-page .home-popular-list {
  padding-left: 0;
  margin-left: 0;
  gap: 0;
  row-gap: 0;
}
.mw-page #mwFileList { gap: 0; row-gap: 0; }
/* Files-tab list rows — visual parity with /free and /explore.
   Borderless except for a single bottom hairline (the same darker
   --gray-mid mix /free uses), 16px left gutter so rows feel inset,
   transparent background at rest so the page surface shows through.
   The hover/active rule below paints the row white and lifts it on
   a soft drop-shadow exactly like /free, then suppresses the
   bottom hairline so the elevation does the visual work alone. */
.mw-page .home-popular-list .activity-item {
  position: relative;
  border: none;
  border-bottom: 0.75px solid color-mix(in srgb, var(--gray-mid) 40%, transparent);
  border-radius: 0;
  background: transparent;
  margin-top: 0;
  margin-bottom: 0;
  margin-left: var(--space-4);
  margin-right: 0;
  box-shadow: none;
}
.mw-page .home-popular-list .activity-item:first-child { border-top: none; }
/* Inner detail pages (project / kit) — drop the 16px left margin so the
   file rows align flush with the search bar and select-row above. */
.mw-page--detail .home-popular-list .activity-item {
  margin-left: 0;
}
/* Project-inner info-row alignment: rows have margin-left: 0 and
   padding-left: 24px (--space-6), so the row title sits 24px in
   from the container edge and the row checkbox sits at -20px
   (--space-5) from that. Scoped to .mw-pd (project-inner only) —
   program-participant uses .mw-projgrid (40px padding) instead of
   activity-item rows, so it keeps the default info-row geometry. */
.mw-pd .mw-info-row {
  padding-left: var(--space-6);
}
.mw-pd .mw-select-all-box {
  left: calc(-1 * var(--space-5));
}

/* ---------- Program panel: program-as-course container ----------
   The program is a course; the kits inside are its sessions. The
   panel renders the program as the OUTER container with header
   (title + program badge + description + session count) and a body
   that nests the kit grid as session cards. Uses the same
   --space-* and --border-primary tokens as the rest of work.css. */
.mw-program-panel {
  margin: var(--space-5) var(--space-10) 0;
  border-radius: 16px;
  background: var(--white);
  box-shadow: var(--ew-preview-section-shadow);
  overflow: hidden;
}
@media (max-width: 768px) {
  .mw-program-panel { margin: var(--space-4) 0 0; border-radius: 12px; }
}
.mw-program-panel-head {
  padding: var(--space-5) var(--space-6) var(--space-4);
  border-bottom: 0.75px solid var(--gray-light);
  background: var(--gray-white);
}
/* Compact head: program title + description live in the page hero
   above, so the panel only needs a slim band for the session count. */
.mw-program-panel-head--compact {
  padding: var(--space-3) var(--space-6);
  background: transparent;
  border-bottom: 0.75px solid var(--gray-light);
}
.mw-program-panel-title-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.mw-program-panel-title {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--navy);
  line-height: 1.3;
}
.mw-program-panel-desc {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  color: var(--ink-2);
  line-height: 1.45;
}
.mw-program-panel-meta {
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  color: var(--gray-mid);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Session grid sits INSIDE the panel — drop the outer 40px gutter
   that .mw-projgrid normally adds (the panel already pads its body)
   and reset the top margin so it hugs the panel header. */
.mw-program-panel .mw-program-sessions {
  margin: 0;
  padding: var(--space-5) var(--space-6);
}

/* Session cards sit inside .mw-program-panel which already carries
   the soft preview shadow — its gray-background body would swallow
   the same shadow on the kits inside. Switch them to a 1px border
   + smaller --shadow-sm so the cards still read as lifted chrome
   against the panel surface. Both come from tokens. */
.mw-program-panel .mw-projcard {
  border: 0.75px solid var(--gray-light);
  box-shadow: var(--shadow-sm);
}

/* Session card — keeps .mw-projcard chrome (so bulk-select / pin /
   archive / menu JS keeps working) while adding the sequence number
   in the header and a thin progress bar underneath. */
.mw-session-card .mw-projcard-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.mw-session-num {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--gray-light);
  color: var(--gray-mid);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--gray-light);
}
.mw-session-num svg { width: 16px; height: 16px; }
.mw-session-card.is-active .mw-session-num {
  background: var(--navy);
  color: var(--white);
  border-color: var(--navy);
}
.mw-session-card.is-complete .mw-session-num {
  background: var(--success);
  color: var(--white);
  border-color: var(--success);
}

/* Progress bar — sequence/date progress along the session.
   Track uses the same gray-light token as the num bubble; fill
   uses success-green when complete, black when in-progress so it
   reads as the user's "active" state. */
.mw-session-progress {
  margin-top: var(--space-2);
}
.mw-session-progress-track {
  width: 100%;
  height: 4px;
  border-radius: 999px;
  background: var(--gray-light);
  overflow: hidden;
}
.mw-session-progress-fill {
  height: 100%;
  background: var(--navy);
  border-radius: 999px;
  transition: width 240ms ease;
}
.mw-session-card.is-complete .mw-session-progress-fill {
  background: var(--success);
}
/* Hover / persistent-active: clean white card lifted on shadow-xl,
   matching /free. clip-path keeps the shadow from bleeding under the
   right preview column on the joining edge. */
.mw-page .home-popular-list .activity-item:hover,
.mw-page .home-popular-list .activity-item.hover-active,
.mw-page .home-popular-list .activity-item.hover-active:hover {
  background: var(--white);
  box-shadow: var(--shadow-xl);
  border-bottom-color: transparent;
  position: relative;
  z-index: 10;
  clip-path: inset(-50px 0 -50px -50px);
}
/* Open dot-menu lifts the row above siblings + drops the hover clip
   so the dropdown can paint outside the row box (mirrors /free). */
.mw-page .home-popular-list .activity-item:has(.explore-card-menu-wrap.open) {
  position: relative;
  z-index: 60;
  clip-path: none;
  overflow: visible;
}

.mw-page .home-list-col .home-popular-list,
.mw-page .home-list-col .home-search-results {
  height: auto;
  max-height: none;
  overflow: visible;
}
@media (min-width: 768px) {
  .mw-page .home-activity-page .activity-columns {
    grid-template-columns: minmax(0, 1fr) 524px;
  }
}
/* Right preview pane — height-capped to the visible viewport so the
   panel actually FITS under the sticky navbar (Christine, 28 May).
   Without this cap the preview content runs many viewport-heights
   tall, the column's `position: sticky` "works" but the panel's top
   is pinned ABOVE the visible area and only the bottom edge pokes
   through — visually indistinguishable from sticky being broken.
   /free + /explore handle this the same way (free.css L827-830).
       max-height = viewport - navbar - breathing room (space-6)
       overflow-y: auto on the panel so the panel's INNER content
       scrolls inside its fixed window while the column itself stays
       pinned to the navbar as the user scrolls the file list. */
/* Cap the preview panel to the visible viewport. Without this cap the
   panel grows to full content height (~2000px+), the right column
   inherits that height, and `position: sticky` on the column has
   zero room to slide inside its grid container → the preview scrolls
   away with the file list. !important guards against later rules in
   this file (or home-search.css) re-asserting `max-height: none` and
   silently breaking sticky, which has happened twice now. */
.mw-page .home-right-col .activity-preview-panel {
  /* Panel fills the sticky column (which carries the viewport cap at
     L1918) and scrolls internally. Without `height: 100%` on a flex
     child, the panel collapses to its content's intrinsic height and
     can grow past the column's max-height — that's what was making
     the sticky cap silently ineffective. */
  height: 100% !important;
  max-height: 100% !important;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  border-radius: var(--radius-lg);
}
/* .home-right-row2 is no longer rendered on /work — the metadata it
   used to wrap now lives inside the preview pane. Rule kept removed
   intentionally. */
/* Drop the universal 32px push-down on the preview wrapper for /work.
   That cushion exists on /home, /free and /explore so the panel's
   soft drop-shadow falls in empty space below the sticky tabs/search
   row that sits above the right column on those pages. /work doesn't
   have a sticky white row in that position — the info row scrolls
   away — so the gap just leaves the preview pane sitting too low
   relative to the first list row. */
.mw-page .home-right-row1 { margin-top: 0; }
/* Metadata block sits inside the preview pane and REPLACES the
   time · deliverables meta line on /work — that line is marketing
   copy for /free and /explore (deciding to start a product); on /work
   the file already exists, so file facts (Category / Product / Type /
   Last opened / Status / Project) are what the user actually wants.
   Hide the meta line on the Work page and lift the metadata into its
   slot directly under the gradient title divider — no top hairline,
   no extra top spacing. */
.mw-page:not(.free-page) #ep-meta-line { display: none !important; }
.mw-preview-meta {
  box-sizing: border-box;
  background: transparent;
  border: none;
  /* Thin hairline under the metadata strip — separates the file
     facts from the live-preview content (snippets/description)
     below. Same color/weight as the left-list row dividers so it
     reads as part of the established hairline system. */
  border-bottom: 0.75px solid color-mix(in srgb, var(--gray-mid) 40%, transparent);
  border-radius: 0;
  padding: 0 0 var(--space-4);
  /* Mirrors /free's meta-line spacing (margin-top: --space-3,
     margin-bottom: --space-4) so the metadata block sits the same
     distance below the gradient divider and reserves the same
     breathing room above the snippets/description that follow. */
  margin-top: var(--space-3);
  margin-bottom: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 14px;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.45;
  color: var(--navy);
  box-shadow: none;
}
/* Four-column grid. The two existing wrappers (.mw-pmeta-cols and
   .mw-pmeta-stack) are flattened with display:contents so all rows
   become direct grid items of .mw-preview-meta — no markup change
   needed. The Project row spans the full width since it can hold
   long values like "Not added to a project". */
.mw-preview-meta {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: var(--space-5);
  row-gap: 14px;
}
.mw-preview-meta .mw-pmeta-cols,
.mw-preview-meta .mw-pmeta-col,
.mw-preview-meta .mw-pmeta-stack { display: contents; }
/* Project row sits on the second metadata row alongside Last opened
   and Status, spanning the final two columns so its longer values
   (e.g. "Not added to a project") have room to breathe without
   stealing a full row of vertical space. */
.mw-preview-meta #pm-project-row,
.mw-preview-meta #pm-product-row { grid-column: span 2; }
/* Each cell stacks label above value — cleaner at narrow column
   widths than the old inline label · value layout. */
.mw-preview-meta .mw-pmeta-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  min-width: 0;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: normal;
  line-height: 1.45;
  color: var(--navy);
}
.mw-preview-meta .mw-pmeta-label {
  flex: 0 0 auto;
  color: #8a8a8a;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.mw-preview-meta .mw-pmeta-value {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 100%;
  /* Christine (28 May v25): inspector showed this computing to
     #000000 — pin to brand black so the project meta values
     (Report ID, Product, Category, Project, etc.) match the
     brand navy used everywhere else in the preview header. */
  color: var(--navy);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: normal;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Status — sits in the value slot of the Status row.
   Christine (28 May): replaced the filled pill with a coloured
   status dot + black label text so the row reads as data, not as
   a CTA. The colour now lives on the dot only; the badge itself
   is a transparent inline-flex wrapper. */
.mw-preview-meta .mw-pmeta-status-badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: normal;
  line-height: 1.45;
  padding: 0;
  border: 0;
  background: transparent;
  white-space: nowrap;
  color: var(--navy);
}
.mw-preview-meta .mw-pmeta-status-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink-2, #8a8a8a);
  flex: 0 0 auto;
  /* Halo — 5px ring of the same colour at 30% opacity, painted via
     box-shadow spread so it doesn't take grid space. Per-status
     overrides below swap both the core fill and the halo tint. */
  box-shadow: 0 0 0 5px rgba(138, 138, 138, 0.3);
  /* Reserve enough margin around the dot so the halo (5px) clears
     the row's flex gap (--space-1-5 = 6px). */
  margin: 0 4px 0 4px;
}
.mw-preview-meta .mw-pmeta-status-text { color: var(--navy); }
/* Dot colour + halo follows the status, using the canonical
   preview tokens: complete → --positive, progress → --neutral,
   incomplete / failed → --negative. Halo is the same colour at
   30% alpha so it reads as a soft glow around the core. */
.mw-preview-meta .mw-pmeta-status-badge.mw-pmeta-badge-complete .mw-pmeta-status-dot {
  background: var(--positive);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--positive) 30%, transparent);
}
.mw-preview-meta .mw-pmeta-status-badge.mw-pmeta-badge-progress .mw-pmeta-status-dot {
  background: var(--neutral);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--neutral) 30%, transparent);
}
.mw-preview-meta .mw-pmeta-status-badge.mw-pmeta-badge-incomplete .mw-pmeta-status-dot {
  background: var(--negative);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--negative) 30%, transparent);
}
.mw-preview-meta .mw-pmeta-status-badge.mw-pmeta-badge-failed .mw-pmeta-status-dot {
  background: var(--negative);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--negative) 30%, transparent);
}

/* Overall-score chip — sits in the value slot of the Score row,
   shown only for completed leadership_simulation /
   leadership_self_assessment reports. Colour band mirrors the
   in-report score thresholds (low / mid / high). */
.mw-preview-meta .mw-pmeta-score-chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: baseline;
  gap: 1px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: normal;
  line-height: 1;
  padding: var(--space-1) 9px;
  border-radius: 999px;
  border: 0.75px solid transparent;
  white-space: nowrap;
}
.mw-preview-meta .mw-pmeta-score-suffix {
  font-weight: 400;
  opacity: 0.65;
  margin-left: 1px;
}
.mw-preview-meta .mw-pmeta-score-chip.mw-pmeta-score-high {
  color: #1f7a4d; background: var(--gray-light); border-color: #cfe7da;
}
.mw-preview-meta .mw-pmeta-score-chip.mw-pmeta-score-mid {
  color: #a76b14; background: #fbf1de; border-color: #f1dfb8;
}
.mw-preview-meta .mw-pmeta-score-chip.mw-pmeta-score-low {
  color: #b3322a; background: #fbe9e7; border-color: #f3cdc9;
}
/* Sticky preview column.
   !important on `position` + `top` because hover/state rules elsewhere
   (e.g. .home-cards-container:has(...) .home-right-col tint at L1922
   and the home-search.css base .home-right-col rule at L512) sit at
   higher or equal specificity and have, in the past, silently knocked
   sticky off when a new rule was added. Locking position+top here
   guarantees the preview pane stays pinned under the navbar while the
   file list scrolls, which is the whole point of the two-column /work
   layout (Christine, 28 May — preview must stay visible while
   scrolling through files so each row's product is identifiable). */
.mw-page .home-right-col {
  align-self: start !important;
  position: sticky !important;
  top: 70px !important;
  z-index: 5;
  /* Cap the COLUMN height (not just the panel inside) — /free uses
     the same pattern (free.css L781). Without this cap the column
     can grow taller than its slide room inside .activity-columns,
     so as the user scrolls past the top of the column the preview
     scrolls away with the file list. */
  max-height: calc(100vh - 70px - var(--space-6)) !important;
}
.mw-page .home-right-row1 { position: static; }

/* Make absolutely sure none of the top-of-page rows on /work become
   sticky on scroll. Only the right preview column above is sticky;
   everything else (heading, search bar, tabs, info row) scrolls
   normally with the page. */
.mw-page .mw-h1-row,
.mw-page .mw-search-form,
.mw-page .mw-search-form .activity-search-bar,
.mw-page .home-pills-row,
.mw-page .home-pills-row .home-search-row-inner,
.mw-page .free-tabs-row {
  position: static !important;
  top: auto !important;
}
/* .mw-info-row deliberately stays position: relative (set on its
   base rule above) — it's the containing block for the absolutely-
   positioned .mw-select-all-box. Forcing it to position: static
   here strips the containing block and parks the checkbox far
   off-screen. position: relative does NOT make it sticky, so it
   safely satisfies "no sticky info row" too. */
.mw-page .mw-info-row { top: auto !important; }

/* Keep the gap between preview pane and meta panel visible even when a
   left-list item is hovered/active. The shared rule in home-search.css
   tints the entire .home-right-col to #fafafa on hover, which blends
   the gap with both panels. Override on the Work page so only the
   preview panel itself takes the hover tint. */
.mw-page .home-cards-container:has(.home-popular-list .activity-item:hover) .home-right-col,
.mw-page .home-cards-container:has(.home-popular-list .activity-item.hover-active) .home-right-col {
  background: transparent;
}

/* Info row under the tabs (Claude-style "Your Renatus files Select" / "# selected …").
   Left padding matches the row content offset below: rows have
   margin-left: var(--space-4) (16px) + internal padding-left 24px
   = 40px from container edge before the title text starts. The
   info-row content (count + actions) lines up with that title
   column, and the absolutely-positioned select-all box (offset
   below) lines up with the per-row checkbox column. */
.mw-info-row {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 0 0 var(--space-10);
  width: 100%;
  max-width: 1310px;
  margin-left: auto;
  margin-right: auto;
  box-sizing: border-box;
  min-height: 36px;
  font-size: var(--text-sm);
  color: var(--gray-mid);
}
.mw-info-row .mw-info-left {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--space-6);
}
/* Default (non-selecting) variant — "Your files" + "Select" button.
   Use baseline alignment so the "Select" link sits on the same
   text baseline as the label (not vertically centred against the
   button's box, which floats it ~2px above the label). */
.mw-info-row .mw-info-default {
  align-items: baseline;
}
.mw-info-row .mw-info-left > *,
.mw-info-row .mw-info-actions > * {
  line-height: var(--space-6);
  display: inline-flex;
  align-items: center;
}
/* Children of the default variant render as inline-block instead of
   inline-flex so the parent's align-items: baseline can act on the
   text baseline of each child (inline-flex collapses children to a
   replaced-element baseline that ignores text). */
.mw-info-row .mw-info-default > * {
  display: inline-block;
}
.mw-info-row .mw-info-actions {
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
}
/* Spacing between the count number and "selected" word.
   The outer .mw-info-left > span gets display: inline-flex from
   the rule above, which makes " selected" a flex item whose
   leading whitespace is trimmed. Push the count span away with
   margin-right so all 4 pages get consistent spacing regardless
   of the per-page count id (mwBulkCount, mwProjBulkCount,
   mwLibBulkCount, mwProgBulkCount). */
.mw-info-row .mw-bulk-count { margin-right: 4px; }
.mw-page.is-selecting .mw-info-default { display: none; }
.mw-page:not(.is-selecting) .mw-info-selecting { display: none; }

.mw-select-link {
  background: none;
  border: 1px solid var(--gray-mid);
  border-radius: 6px;
  padding: 2px 8px;
  margin-left: var(--space-1-5);
  color: var(--gray-mid);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: inherit;
  cursor: pointer;
  text-decoration: none;
}
.mw-select-link:hover { color: var(--navy); border-color: var(--navy); }

.mw-select-all-box {
  position: absolute;
  /* Absolute positioning is relative to .mw-info-row's padding box
     (its left edge), NOT its content edge — so the row's
     padding-left: 40px does not shift the reference. The per-row
     checkboxes below sit at section-left - 4px (rows are at
     margin-left 16px, their checkbox at left: -20px from the row).
     .mw-info-row also starts at section-left, so left: -4px puts
     this box in the same column. */
  left: calc(-1 * var(--space-1));
  top: 50%;
  transform: translateY(-50%);
  width: var(--space-4);
  height: var(--space-4);
  margin: 0;
  padding: 0;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: opacity 120ms ease;
}
/* Custom checkbox: outlined box, black tick, no fill on check */
.mw-select-all-box,
.mw-frow-check {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  border: 1.5px solid var(--gray-mid);
  border-radius: 3px;
}
.mw-frow-check { position: absolute; }
.mw-select-all-box:checked,
.mw-frow-check:checked {
  background: transparent;
  border-color: var(--navy);
}
.mw-select-all-box:checked::after,
.mw-frow-check:checked::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--space-1);
  height: var(--space-2);
  border: solid var(--navy);
  border-width: 0 2px 2px 0;
  transform: translate(-50%, -60%) rotate(45deg);
}
/* Select-all box is hidden until the user explicitly enters
   selecting mode by clicking "Select" (which adds .is-selecting
   to .mw-page). Previously it appeared on hover (desktop) and
   was always visible (mobile), which was confusing. */
.mw-page.is-selecting .mw-select-all-box {
  opacity: 1;
  visibility: visible;
}

/* Mobile: there's no hover on touch, so the select-all box is
   always visible. Align it horizontally with the per-row
   checkboxes below (both sit at left: -6px from their row's
   left edge so they share the same vertical column).

   We also restore position: relative on .mw-info-row — an
   earlier rule forces it to position: static !important, which
   stripped the containing block from the absolutely-positioned
   select-all box and parked it at the viewport centre. */

/* ── Preview slab CTA — global token palette ──────────────────────────────
   Token-driven so desktop + mobile + /free + /explore all share one source.
   Mobile block below adds full-width layout on top; colours come from here. */
:root {
  --rip-cta-bg: var(--navy);
  --rip-cta-fg: var(--white);
  --rip-cta-hover-bg: var(--pink);
}
.row-inline-preview .rip-cta {
  background: var(--rip-cta-bg);
  color: var(--rip-cta-fg);
  border: none;
  border-radius: 6px;
  padding: 8px var(--space-4);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.row-inline-preview .rip-cta:hover,
.row-inline-preview .rip-cta:focus {
  background: var(--rip-cta-hover-bg);
  color: var(--white);
}

@media (max-width: 768px) {
  /* Lock all My Work search bars to the same 44px pill height used
     on /free and /explore. Higher specificity than the shared
     .home-search-bar--hero rule so this wins regardless of source
     order. Excludes .mw-pd (project-detail chat input) which is a
     tall multi-line composer, not a search bar. */
  .mw-page:not(.mw-pd) .mw-search-form .activity-search-bar {
    height: 44px;
    min-height: 44px;
    padding: var(--space-2) var(--space-4);
  }
  /* Project-detail search bar (work_project.html) sits in .mw-pd but
     was reset to a plain 58px input on .mw-page--detail. Bring it down
     to 44px on phones too so it matches the other My Work pages. */
  .mw-page--detail .mw-pd .mw-search-form .activity-search-bar,
  .mw-pd .mw-search-form--with-action .activity-search-bar,
  .mw-pd .mw-search-form-action {
    height: 44px;
    min-height: 44px;
  }

  /* Push the info-row content (bulk count "0", "selected", action
     icons) in by 24px so it aligns with the file title text below
     (which sits at 48px from the screen edge: 24px mw-page gutter
     + 24px row padding-left). */
  .mw-page .mw-info-row {
    position: relative !important;
    padding-left: var(--space-6);
  }
  /* Align the select-all box with the per-row checkboxes below.
     Per-row check is at left: -6px relative to its row (left edge
     at 24px from screen → 18px). The info-row starts at the same
     24px, so left: -6px puts the select-all in the same column.
     Visibility is gated globally on .mw-page.is-selecting (see
     above), so we don't override opacity/visibility here. */
  .mw-select-all-box {
    left: calc(-1 * var(--space-1-5));
  }
  /* On mobile, keep 24px of left padding inside the row so the
     per-row select checkbox (positioned absolutely at left: -6px)
     has room to render and stay tappable. Right padding stays 0
     so the kebab can sit flush to the page edge. Scoped to
     .mw-page so /free and /explore are unaffected.
     Height 72px (down from the 100px desktop default) matches the
     same mobile shrink applied to /free + /explore so the three
     pages share the same row footprint on phones. */
  .mw-page .home-popular-list .activity-item.explore-item.mw-frow {
    padding-left: var(--space-6);
    padding-right: 0;
    height: 72px !important;
    min-height: 72px !important;
    max-height: 72px !important;
  }
  /* Right column: shrink to fit the kebab and align right.
     Drops the 44px min-width that was reserved for the
     star + kebab pair (star is hidden on mobile). */
  .mw-page .mw-frow .activity-item-actions {
    min-width: 0;
    gap: 0;
    justify-content: flex-end;
  }
  /* Keep the file list inside the 24px page gutter. Two desktop
     "bleed" tricks were pushing rows past it:
       1) .home-popular-list uses margin:0 -30px + padding:0 30px
          to extend edge-to-edge inside a wider card.
       2) .mw-frow uses margin:0 -12px for the same reason.
     Both are scoped to .mw-page so /free and /explore (which
     share these classes) are not affected. */
  .mw-page .home-popular-list {
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
    padding-right: 0;
  }
  .mw-page .mw-frow {
    margin-left: 0;
    margin-right: 0;
  }
  /* Push the kebab icon flush to the row's right edge by removing
     its 4px right padding (padding stays on the other sides so the
     hit target keeps its size). */
  .mw-page .mw-frow .explore-card-menu-trigger {
    padding-right: 0;
  }
  /* Hide the "Star" item from the row dropdown on mobile —
     starring is desktop-only on /work. The star button on the row
     itself is already hidden on mobile via .mw-frow-star. */
  .mw-page .mw-menu-dropdown .mw-menu-item--star {
    display: none;
  }
  /* Mobile click-to-expand inline preview, mirroring /free + /explore.
     The slab is injected by the script in work.html below the tapped
     row and renders a short snippet + "View" / "Continue" CTA. */
  .mw-page .row-inline-preview { display: none; }
  /* Dark overlay behind the selected card — covers the full viewport
     at z-index 9 (just below the row/slab at z-index 10). Tapping it
     does nothing (pointer-events:none) — the click listener on the
     document handles deselection. */
  .mw-page.has-rip-open::before {
    content: '';
    position: fixed;
    inset: 0;
    background: rgba(15, 30, 65, 0.35);
    z-index: 9;
    pointer-events: none;
  }
  /* Title row: activate the same desktop shadow (hover-active adds it
     via JS) but allow right-side bleed — desktop clips right=0 for its
     two-column layout; on mobile the list is full-width so all four
     sides can bleed.  Clip bottom so shadow doesn't leak into the slab. */
  /* On mobile, cancel the desktop :hover shadow so it doesn't linger
     after a tap on non-selected rows. */
  .mw-page .home-popular-list .activity-item:hover:not(.hover-active) {
    background: transparent;
    box-shadow: none;
    clip-path: none;
  }
  /* Selected card: extend the white background 7px each side using a
     box-shadow spread so no layout changes occur and text never moves.
     clip-path controls which sides the shadow bleeds on. */
  .mw-page .home-popular-list .activity-item.hover-active,
  .mw-page .home-popular-list .activity-item.hover-active:hover {
    border-radius: var(--radius-lg) var(--radius-lg) 0 0 !important;
    border-bottom: none !important;
    box-shadow: 0 0 0 7px var(--white), var(--shadow-xl) !important;
    clip-path: inset(-50px -50px 0 -50px);
  }
}
/* Touch devices only — cancel the lingering :hover highlight that
   appears after tap-to-deselect. Desktop (hover:hover) is unaffected. */
@media (hover: none) {
  .mw-page .home-popular-list .activity-item:not(.hover-active):hover {
    background: transparent !important;
    box-shadow: none !important;
    border-bottom-color: var(--gray-light) !important;
    clip-path: none !important;
  }
}
@media (max-width: 768px) {
  /* Slab (data + CTA): matching bottom shadow.
     Clip top flush so it doesn't bleed into the title row above. */
  .mw-page .row-inline-preview.open {
    display: block;
    padding: 0 var(--space-6) var(--space-4);
    background: var(--white);
    border-top: none;
    position: relative;
    z-index: 10;
    margin-left: -5px;
    margin-right: -5px;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    box-shadow: 0 0 0 2px var(--white), var(--shadow-xl);
    clip-path: inset(0 -50px -50px -50px);
  }
  .mw-page .row-inline-preview .rip-loading {
    font-size: 13px;
    color: #888;
    padding: var(--space-1) 0;
  }
  .mw-page .row-inline-preview .rip-desc {
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--navy);
    padding: 2px 0 var(--space-1);
    /* Reveal at most 4 lines of the standfirst, then ellipsis. The
       full text is still available inside the report itself. */
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* In-progress / failed message rendered in place of the standfirst
     when an incomplete file is tapped. Mirrors the desktop right-pane
     in-progress treatment but reuses the existing inline-preview CTA
     styling beneath, so visually it just feels like the standfirst
     text was swapped out for an explanatory message. */
  .mw-page .row-inline-preview .rip-inprog {
    padding: 2px 0 var(--space-1);
  }
  .mw-page .row-inline-preview .rip-inprog .rip-inprog-msg {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--navy);
  }
  /* Report metadata block — mirrors the desktop right-pane layout
     exactly: a two-column grid (Category/Product/Type on the left,
     Subcategory or Market/Last opened/Status on the right) with a
     full-width Project (or Program) row stacked beneath. */
  .mw-page .row-inline-preview .rip-meta {
    margin-bottom: var(--space-3);
    font-size: 13px;
    line-height: 1.45;
    color: var(--navy);
  }
  .mw-page .row-inline-preview .rip-meta-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-4);
  }
  .mw-page .row-inline-preview .rip-meta-col {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 0;
  }
  .mw-page .row-inline-preview .rip-meta-stack {
    margin-top: var(--space-2);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
  }
  .mw-page .row-inline-preview .rip-meta-row {
    display: flex;
    align-items: baseline;
    gap: var(--space-1-5);
    min-width: 0;
  }
  .mw-page .row-inline-preview .rip-meta-label {
    flex: 0 0 auto;
    color: #8a8a8a;
    white-space: nowrap;
  }
  .mw-page .row-inline-preview .rip-meta-val {
    flex: 1 1 auto;
  }
  .mw-page .row-inline-preview .rip-id-val {
    flex: 0 0 auto;
    min-width: 0;
    color: var(--navy);
    word-break: break-word;
    margin-right: 20px;
  }
  .mw-page .row-inline-preview .rip-sub-val {
    flex: 0 0 auto;
    color: var(--navy);
    margin-right: 20px;
  }
  .mw-page .row-inline-preview .rip-cta-wrap {
    margin-top: var(--space-3);
  }
  .mw-page .row-inline-preview .rip-cta {
    display: block;
    width: 100%;
    box-sizing: border-box;
    text-align: center;
    padding: 11px var(--space-4);
  }
  /* Status dot — replaces "Status:" text label; mirrors desktop mw-pmeta-status-dot */
  .mw-page .row-inline-preview .rip-status-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ink-2, #8a8a8a);
    box-shadow: 0 0 0 5px rgba(138, 138, 138, 0.3);
    flex: 0 0 auto;
    align-self: center;
    margin: 0 4px 0 4px;
  }
  .mw-page .row-inline-preview .rip-sd-complete {
    background: var(--positive);
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--positive) 30%, transparent);
  }
  .mw-page .row-inline-preview .rip-sd-in-progress {
    background: var(--neutral);
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--neutral) 30%, transparent);
  }
  .mw-page .row-inline-preview .rip-sd-incomplete,
  .mw-page .row-inline-preview .rip-sd-failed {
    background: var(--negative);
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--negative) 30%, transparent);
  }
  /* Row 1: ID group · subcategory · status group — all inline, 15px between groups */
  .mw-page .row-inline-preview .rip-meta-row--r1 {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 15px;
    flex-wrap: nowrap;
    margin-bottom: 4px;
  }
  .mw-page .row-inline-preview .rip-id-group {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    flex-shrink: 0;
  }
  .mw-page .row-inline-preview .rip-id-group .rip-meta-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: #8a8a8a;
    white-space: nowrap;
  }
  .mw-page .row-inline-preview .rip-id-val {
    font-size: 13px;
    color: var(--navy);
    flex-shrink: 0;
  }
  .mw-page .row-inline-preview .rip-sub-val {
    font-size: 13px;
    color: var(--navy);
    flex-shrink: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .mw-page .row-inline-preview .rip-status-group {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex-shrink: 0;
  }
  .mw-page .row-inline-preview .rip-status-label {
    font-size: 13px;
    color: var(--navy);
    white-space: nowrap;
  }
  /* Row 2: PROJECT / PROGRAM label + value on one line */
  .mw-page .row-inline-preview .rip-meta-row--r2 {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    gap: 6px;
    flex-wrap: nowrap;
  }
  .mw-page .row-inline-preview .rip-meta-row--r2 .rip-meta-label {
    flex-shrink: 0;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: #8a8a8a;
    white-space: nowrap;
  }
  .mw-page .row-inline-preview .rip-meta-row--r2 .rip-meta-val {
    font-size: 13px;
    color: var(--navy);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }

  /* When a row's preview slab is open, leave the row's own
     background untouched (white) — previously we tinted it the
     same #fafafa as the slab, which caused the row's bottom
     hairline divider to blend into the tint and visually disappear.
     The slab's own border-top now provides the separation between
     the row and its slab, and the row's hairline stays visible
     against white as it does for every other row in the list. */

  /* Kit detail page (mw-page--kit): hide the right-aside Memory /
     Instructions / Project files panels and the desktop hover
     preview pane on mobile, AND collapse the parent two-column
     grid so the left column gets the full viewport width.
     Without the grid override the empty aside still claims 35% and
     pushes the step cards off the right edge. Tapping a step card
     instead expands an inline preview slab beneath it (see
     work_kit.html JS), matching the /work mobile pattern. */
  .mw-page--kit .mw-pd {
    grid-template-columns: 1fr;
    gap: 0;
  }
  .mw-page--kit .mw-pd > aside {
    display: none !important;
  }
  /* Detail pages strip the default .mw-page 24px side gutter
     because the desktop two-column grid handles its own spacing.
     With the grid collapsed to one column on mobile we restore
     the standard 24px gutter to match the rest of the mobile app. */
  .mw-page--kit {
    padding-left: var(--space-6);
    padding-right: var(--space-6);
  }
  .mw-page--kit .mw-kit-preview,
  .mw-page--kit aside .mw-panel--grouped {
    display: none !important;
  }
  /* Force single-column on mobile so the inline preview slab
     (inserted as a sibling between cards) always spans full width
     beneath the tapped card. Also tighten the slab's border so it
     reads as a continuation of the card above. */
  .mw-page--kit .mw-kit-cards {
    grid-template-columns: 1fr;
  }
  .mw-page--kit .mw-kit-cards .row-inline-preview.open {
    border-radius: 12px;
    border: 1px solid var(--gray-light);
    margin: calc(-1 * var(--space-1)) 0 var(--space-1);
  }
}

.mw-info-actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-left: var(--space-3);
}
.mw-info-icon-btn {
  background: none;
  border: 0;
  cursor: pointer;
  padding: var(--space-1-5);
  border-radius: 6px;
  color: var(--gray-mid);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.mw-info-icon-btn:hover {
  background: var(--bg-hover);
  color: var(--navy);
}
.mw-info-icon-btn svg {
  width: var(--space-4);
  height: var(--space-4);
  stroke: currentColor;
  fill: none;
  stroke-width: 1.7;
}
.mw-info-icon-btn.danger:hover { color: var(--negative); }
/* Close (X) sits inline immediately after the "N selected" text,
   not pushed to the far right. The bulk-action icons follow it. */
.mw-info-close { margin-left: 0; }

.mw-empty {
  padding: var(--space-12) var(--space-6);
  text-align: center;
  color: var(--gray-mid);
  font-size: var(--text-sm);
}
.mw-empty a {
  color: var(--insights-primary);
  text-decoration: none;
  font-weight: var(--font-weight-medium);
}

/* Local card-menu dropdown for our row actions */
.mw-menu-dropdown {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + var(--space-1));
  background: var(--white);
  border: 1px solid var(--gray-light);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  min-width: 200px;
  z-index: 50;
  padding: var(--space-1-5);
}
.explore-card-menu-wrap.open .mw-menu-dropdown { display: block; }
.mw-page .mw-frow .explore-card-menu-trigger {
  opacity: 0;
  visibility: hidden;
  transition: opacity 120ms ease;
}
.mw-page .mw-frow:hover .explore-card-menu-trigger,
.mw-page .mw-frow .explore-card-menu-wrap.open .explore-card-menu-trigger {
  opacity: 1;
  visibility: visible;
}
@media (max-width: 768px) {
  .mw-page .mw-frow .explore-card-menu-trigger {
    opacity: 1;
    visibility: visible;
  }
}
.mw-menu-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  color: var(--navy);
  text-decoration: none;
  cursor: pointer;
  background: none;
  border: 0;
  width: 100%;
  text-align: left;
  font-family: inherit;
  border-radius: var(--radius-md);
}
.mw-menu-item svg {
  width: var(--space-4);
  height: var(--space-4);
  flex-shrink: 0;
}
.mw-menu-item:hover { background: var(--bg-hover); }
.mw-menu-item.danger { color: var(--negative); }
.mw-menu-divider {
  height: 1px;
  background: var(--gray-light);
  margin: 6px var(--space-1);
}

/* Standard centered modal */
.mw-modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--overlay-bg);
  z-index: 2000;
  align-items: center;
  justify-content: center;
}
.mw-modal-overlay.open { display: flex; }
/* Base .mw-modal-card — Tier B/C chrome is supplied by the global
   .mw-modal-overlay .mw-modal-card rule below. This base only sets
   the surface (background, sizing, flex direction). Padding, gap,
   border-radius, box-shadow live on the overlay-scoped rule so EVERY
   modal under .mw-modal-overlay inherits the canonical Tier B chrome
   automatically — no per-modal allow-list. May 9 2026, Christine. */
.mw-modal-card {
  background: var(--white);
  width: 440px;
  max-width: calc(100% - var(--space-8));
  display: flex;
  flex-direction: column;
}
.mw-modal-title {
  font-size: var(--text-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--navy);
  margin: 0;
}
.mw-modal-label {
  font-size: var(--text-xs);
  color: var(--gray-mid);
  margin-bottom: var(--space-1-5);
  display: block;
}
.mw-modal-input {
  width: 100%;
  box-sizing: border-box;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  color: var(--navy);
  background: var(--white);
  border: 1px solid var(--gray-light);
  border-radius: var(--radius-md);
  font-family: inherit;
  outline: none;
}
.mw-modal-input:focus { border-color: var(--navy); }
.mw-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}

/* Confirm modal — title + body + right-aligned actions */
.mw-modal-card.mw-confirm-card {
  width: 480px;
  padding: var(--space-7) var(--space-7) 22px;
  gap: var(--space-3);
}
.mw-modal-card.mw-confirm-card .mw-modal-title {
  font-size: var(--text-xl);
  font-weight: var(--font-weight-semibold);
}
.mw-confirm-body {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-2);
}
.mw-confirm-credits {
  margin: var(--space-2) 0 0;
  font-size: var(--text-xl);
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
  color: var(--gray-darkest, var(--ink-2));
}
.mw-confirm-credits strong { font-weight: inherit; }
.mw-modal-card.mw-confirm-card .mw-modal-actions { margin-top: var(--space-2); }

/* Action button used by the shared confirm modal
   (templates/components/work/_modals.html). Renders as a black
   pill (matching .btn-primary in base.css) instead of the red
   "danger" colour — per design preference, the destructive
   intent is conveyed by the modal copy rather than colour. The
   .btn-danger class is still used in markup so existing JS hooks
   keep working. */
.mw-modal-actions .btn-danger {
  padding: var(--space-2) var(--space-4);
  font-size: 13px;
  font-weight: var(--font-medium);
  font-family: inherit;
  background: var(--navy);
  color: var(--white);
  border: 1px solid var(--navy);
  border-radius: var(--radius-full, 30px);
  cursor: pointer;
  transition: filter 0.15s ease;
}
.mw-modal-actions .btn-danger:hover { filter: brightness(0.92); }

/* ============================================================
   Tier B INFO modal — single-CTA notification dialog.
   Same chrome as Tier B: gradient stripe at top, white card,
   dark heading, pink pill OK button. Used by mwInfo() helper
   in static/js/work-shared.js as a styled alert() replacement.
   ============================================================ */
.mw-modal-card.mw-info-card {
  width: var(--ta-modal-max-width, 440px);
  padding: 0;                             /* stripe + sections own their own padding */
  gap: 0;
  border-radius: 0 0 var(--ta-modal-radius-bottom, 16px) var(--ta-modal-radius-bottom, 16px);
  box-shadow: var(--tb-card-shadow, none);
  overflow: hidden;
}
.mw-info-card .mw-modal-stripe {
  height: var(--tb-stripe-height, 3px);
  background: var(--tb-stripe-bg);
}
.mw-info-card .mw-info-head {
  padding: var(--ta-head-pad-y, 22px) var(--ta-modal-pad-x, 28px) 0;
}
.mw-info-card .mw-info-head .mw-modal-title {
  /* padding:0 — the wrapping `.mw-info-head` already owns the head
     inset (`--ta-head-pad-y` × `--ta-modal-pad-x`). Without this
     reset, the canonical `.mw-modal-overlay .mw-modal-title` rule
     adds the same inset *again*, double-padding the heading by ~56px
     on the left so it reads as centered instead of left-aligned. */
  margin: 0;
  padding: 0;
  text-align: left;
  font-size: var(--ta-heading-size, 20px);
  font-weight: var(--ta-heading-weight, 600);
  color: var(--tb-heading-color);
  letter-spacing: var(--tb-heading-letter-spacing, -0.01em);
  line-height: var(--tb-heading-line-height, normal);
}
.mw-info-card .mw-info-body-wrap {
  padding: var(--tb-gap-head-to-body, 32px) var(--ta-modal-pad-x, 28px) 0;
}
.mw-info-card .mw-info-body {
  margin: 0;
  font-size: var(--ta-paragraph-size, 14.5px);
  font-weight: var(--ta-paragraph-weight, 400);
  line-height: var(--ta-paragraph-line-height, 1.6);
  color: var(--ta-paragraph-color, var(--ink-2));
  white-space: pre-line;
}
.mw-info-card .mw-info-callout {
  margin-top: var(--tc-callout-gap, 20px);
  padding: var(--tc-callout-pad-y, 10px) var(--tc-callout-pad-x, 14px);
  background: var(--tc-callout-bg);
  color: var(--tc-callout-color);
  font-size: var(--tc-callout-size, 13px);
  font-weight: var(--tc-callout-weight, 500);
  border-radius: var(--tc-callout-radius, 10px);
  line-height: 1.5;
}
.mw-info-card .mw-info-actions {
  padding: var(--ta-foot-pad-top, 18px) var(--ta-modal-pad-x, 28px) var(--ta-foot-pad-bottom, 24px);
  margin-top: var(--tb-gap-body-to-foot, 24px);
  gap: var(--ta-foot-gap, 10px);
  justify-content: flex-end;
}
.mw-info-card .mw-tb-primary {
  appearance: none;
  border: 0;
  font-family: inherit;
  padding: var(--ta-cta-pad-y, 11px) var(--ta-cta-pad-x, 22px);
  min-height: var(--ta-cta-min-height, 40px);
  border-radius: var(--ta-cta-radius, 999px);
  background: var(--ta-cta-feature-bg);
  color: var(--ta-cta-feature-color);
  font-size: var(--ta-cta-feature-size, 14px);
  font-weight: var(--ta-cta-feature-weight, 600);
  cursor: pointer;
  transition: var(--ta-cta-transition, transform .08s ease), background .15s ease;
}
.mw-info-card .mw-tb-primary:hover {
  background: var(--tb-cta-feature-hover-bg);
  transform: translateY(var(--ta-cta-hover-lift, -1px));
}

/* Description paragraph used inside .mw-modal-card. */
.mw-modal-desc {
  margin: var(--space-1) 0 var(--space-4);
  color: var(--ink-2);
  font-size: 14px;
  line-height: 1.5;
}

.mw-mr-login-note {
  font-size: 13px;
  color: var(--ink-2);
  align-self: center;
}
.mw-mr-login-link { color: var(--pink); }
.mw-mr-login-link:hover { opacity: 0.8; }
#mrModal.mw-modal-overlay { top: var(--topbar-height, 72px); }
#mrModal .mw-modal-title { margin-bottom: 20px; }
#mrModal .mw-modal-actions { justify-content: flex-start; }

/* Move-to-project modal (larger, search + list) */
.mw-modal-card.mw-move-card {
  width: 560px;
  padding: var(--space-7);
  gap: 14px;
  position: relative;
}
.mw-modal-close {
  position: absolute;
  top: var(--space-4-5);
  right: var(--space-4-5);
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  padding: 0;
  color: var(--gray-mid);
  cursor: pointer;
  border-radius: 6px;
}
.mw-modal-close:hover {
  background: var(--bg-hover);
  color: var(--navy);
}
.mw-modal-subtitle {
  font-size: var(--text-sm);
  color: var(--gray-mid);
  margin: 0;
  line-height: 1.45;
}
.mw-modal-subtitle b {
  color: var(--navy);
  font-weight: var(--font-weight-semibold);
}
.mw-move-list-wrap {
  border: 1px solid var(--gray-light);
  border-radius: 14px;
  background: var(--white);
  overflow: hidden;
}
.mw-move-search-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 14px;
  border-bottom: 1px solid var(--gray-light);
}
.mw-move-search-row svg {
  width: 18px;
  height: 18px;
  color: var(--gray-mid);
  flex-shrink: 0;
}
.mw-move-search {
  flex: 1;
  border: 0;
  outline: 0;
  background: transparent;
  font-size: var(--text-sm);
  font-family: inherit;
  color: var(--navy);
}
.mw-move-search::placeholder { color: var(--gray-mid); }
.mw-move-list {
  max-height: 340px;
  overflow-y: auto;
  padding: var(--space-1-5);
}
.mw-move-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  background: none;
  border: 0;
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: left;
  font-size: var(--text-sm);
  color: var(--navy);
  font-family: inherit;
}
.mw-move-item:hover,
.mw-move-item.active { background: var(--bg-hover); }
.mw-move-item svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--ink-2);
}
.mw-move-item.create { color: var(--pink); }
.mw-move-item.create svg { color: var(--pink); }
.mw-move-empty {
  padding: var(--space-6) 14px;
  text-align: center;
  font-size: var(--text-xs);
  color: var(--gray-mid);
}

.mw-inprog {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: var(--space-2);
  vertical-align: middle;
}
.mw-inprog .dot {
  width: 5px;
  height: 5px;
  border-radius: var(--radius-full);
  background: var(--pink);
  animation: mwPulse 1.4s ease-in-out infinite;
}
.mw-inprog .dot:nth-child(2) { animation-delay: 0.2s; }
@keyframes mwPulse {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}

.ep-snippet-item {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--navy);
}
.ep-snippet-num {
  font-weight: var(--font-weight-semibold);
  color: var(--gray-mid);
  flex-shrink: 0;
  min-width: 18px;
}
.ep-snippet-text { flex: 1; }

.mw-page .ep-bottom-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.ep-bottom-stat {
  border: 1.5px solid var(--navy);
  border-radius: var(--radius-md);
  padding: var(--space-3) 14px;
  display: flex;
  flex-direction: column;
  gap: var(--space-1-5);
}
.ep-bottom-stat-label {
  font-size: var(--text-xs);
  color: var(--ink-2);
  line-height: 1.35;
}
.ep-bottom-stat-value {
  font-size: var(--text-xl);
  font-weight: var(--font-weight-bold);
  line-height: 1.15;
  color: var(--navy);
  letter-spacing: -0.01em;
}

.ep-credits { padding-top: 14px; }
.ep-credits-grid {
  display: flex;
  gap: var(--space-3);
}
.ep-credits-grid > * { flex: 1; }

/* Preview CTAs (used by JS-rendered preview content) */
.mw-preview-cta-primary,
.mw-preview-cta-secondary {
  display: block;
  text-align: center;
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-md);
  text-decoration: none;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
}
.mw-preview-cta-primary {
  background: var(--navy);
  color: var(--white);
}
.mw-preview-cta-secondary {
  background: var(--white);
  color: var(--navy);
  border: 1px solid var(--gray-light);
}

/* "LIVE PREVIEW" eyebrow above the snippets list — same uppercase
   tracked styling as the metadata column labels so the two read as
   peers. Tight bottom margin since the snippet rows that follow
   already provide their own row gap. */
.mw-page .ep-live-preview-heading {
  margin: 10px 0 var(--space-3);
  padding: 0;
  color: var(--navy);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.45;
}

/* Replace the numeric "1./2./3." prefixes on /work's LIVE PREVIEW
   key-findings snippets with a filled right-triangle marker (▸).
   Scoped to .mw-page so /home and /explore are unaffected. */
.mw-page #ep-snippets .ep-snippet-num { display: none; }
.mw-page #ep-snippets .ep-snippet-item {
  align-items: flex-start;
  /* Christine (28 May v7): zero the flex gap and pull the text
     5px further left with a negative right-margin on the marker
     (see ::before rule below). Flexbox `gap` is clamped to ≥0 per
     spec so negative-gap can't go through `gap` directly. Net
     effect: marker→text spacing was 8px → 3px → -2px. */
  gap: 0;
}
.mw-page #ep-snippets .ep-snippet-item::before {
  /* LIVE PREVIEW marker — Christine (28 May v4): brand arrow.svg
     (Assets/Icons/arrow.svg, mirrored to static/images/icons/arrow.svg).
     Cyan dashed-tail + filled triangle, 42.1 × 22 viewBox (aspect
     ~1.91:1). The SVG is authored in brand cyan #3bc0ff so no
     `color` override needed. */
  content: "";
  display: inline-block;
  flex-shrink: 0;
  /* Christine (28 May v5/v8): two ~10% trims — 32×17 → 29×15 → 26×14
     so the arrow reads as a quiet marker rather than a competing graphic. */
  width: 26px;
  height: 14px; /* 26 × (22 / 42.1) ≈ 13.6 — preserves the 1.91:1 aspect */
  /* Left-aligned within the 32px slot so the arrow tail sits flush
     against the snippet text column rather than floating in the
     middle of the marker box. */
  background: url("/static/images/icons/arrow.svg") no-repeat left center / contain;
  margin-top: 4px; /* optically baseline against the snippet body type */
  margin-right: -2px; /* Christine (28 May v7): pull text 5px closer (was +3 gap, now -2) */
}

/* Drop the inherited 500px fixed heights on /work — both the outer
   preview panel (home-search.css) and the inner preview section
   (home-search.css + explore-work.css) lock to 500px on /home and
   /explore so absolutely-positioned credits/stats anchor inside.
   On /work the right column already auto-heights and we want the
   content to flow naturally without being clipped or padded out
   to a fixed box. Scoped to .mw-page so /home and /explore are
   unaffected. */
/* /home, /free and /explore lock the inner preview-section to 500px
   so absolutely-positioned credits/stats anchor inside. /work needs
   the inner section to flow naturally — so drop the inherited fixed
   height ONLY on the inner section, NOT on the outer panel. The
   outer .activity-preview-panel keeps its viewport-cap from L1717
   so the sticky column above stays shorter than its grid container
   (without that cap, the panel grows to full content height, the
   right column matches it, and sticky has no room to slide → preview
   scrolls away with the file list, which is exactly the bug
   Christine kept hitting). */
.mw-page .home-activity-page .activity-preview-section,
.mw-page .activity-preview-section {
  height: auto;
  max-height: none;
  min-height: 0;
  overflow: visible;
}

/* Empty state in the preview before any hover */
.ep-empty {
  padding: var(--space-10) var(--space-6);
  text-align: center;
  color: var(--gray-mid);
  font-size: var(--text-xs);
  border: 1px dashed var(--gray-light);
  border-radius: var(--radius-lg);
}

/* Selection checkboxes — hidden by default, only shown in select mode */
.home-popular-list .activity-item.mw-frow { position: relative; }
.mw-frow-check {
  position: absolute;
  left: calc(-1 * var(--space-5));
  top: 50%;
  transform: translateY(-50%);
  width: var(--space-4);
  height: var(--space-4);
  cursor: pointer;
  opacity: 1;
  margin: 0;
  flex-shrink: 0;
  z-index: 2;
  accent-color: var(--navy);
  display: none;
}
.mw-page.is-selecting .mw-frow-check { display: block; }

/* Mobile: nudge the row checkbox 8px to the right (left: -20px → -12px)
   so it sits closer to the row content and away from the screen edge. */
@media (max-width: 768px) {
  .mw-frow-check { left: -6px; }
}
.home-popular-list .activity-item.mw-frow.selected { background: var(--bg-hover); }

/* Step number badge — used in kit in-project view to show sequential step order */
.mw-frow-num {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--gray-light);
  color: var(--navy);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
  margin-right: var(--space-3);
  user-select: none;
}
.mw-frow-num--empty {
  background: transparent;
  color: var(--gray-mid);
  font-weight: 400;
}
/* In select mode, the leading checkbox slides in over the row's left edge —
   nudge the step number right so they don't collide. */
.mw-page.is-selecting .mw-frow-num { margin-left: 24px; }

/* Preview top blocks — mirror /free and /explore exactly: bolder
   eyebrow, fixed-height title block (so the meta line / content below
   don't shift between 1- and 2-line titles), gradient divider, then
   the time · deliverables meta line. Tokens (sizes, gradient, gray
   colours) are the shared design tokens used on /free + /explore. */
.mw-page .activity-preview-tag {
  margin-bottom: 0;
  /* Christine (28 May v25): inspector showed this computing to
     pure #000000 on /work — pin to brand black so the eyebrow
     tag matches the rest of the preview text. */
  color: var(--navy);
  letter-spacing: 0.14em;
}
.mw-page .activity-preview-title {
  font-size: 18px;
  line-height: 1.5;
  position: relative;
  margin-top: 0;
  margin-bottom: 0;
  min-height: 0;
  display: block;
  /* Christine (28 May v25): /work preview title was inheriting to
     #000000; pin to brand black for parity with /free + /explore. */
  color: var(--navy);
}
/* Christine (28 May v25): preview-pane snippet text + bullet rows
   on /work were rendering pure #000000 — explicit brand-black pin
   so the body copy matches the title/tag above. */
.mw-page .ep-snippet-text,
.mw-page .ep-snippet-item,
.mw-page #ep-description {
  color: var(--navy);
}
/* Title-block reservation — 2 lines × 18px × 1.5 + 12px gap + 3px
   divider = 69px (same calculation as /free). */
.mw-page .activity-preview-combined .ep-title-block {
  min-height: unset;
}
.mw-page .ep-title-divider {
  width: 59px;
  height: 5px;
  margin-top: var(--space-3);
  background:
    linear-gradient(var(--kicker-t10), var(--kicker-t10))  0px 0 / 5px 5px no-repeat,
    linear-gradient(var(--kicker-t09), var(--kicker-t09))  6px 0 / 5px 5px no-repeat,
    linear-gradient(var(--kicker-t08), var(--kicker-t08)) 12px 0 / 5px 5px no-repeat,
    linear-gradient(var(--kicker-t07), var(--kicker-t07)) 18px 0 / 5px 5px no-repeat,
    linear-gradient(var(--kicker-t06), var(--kicker-t06)) 24px 0 / 5px 5px no-repeat,
    linear-gradient(var(--kicker-t05), var(--kicker-t05)) 30px 0 / 5px 5px no-repeat,
    linear-gradient(var(--kicker-t04), var(--kicker-t04)) 36px 0 / 5px 5px no-repeat,
    linear-gradient(var(--kicker-t03), var(--kicker-t03)) 42px 0 / 5px 5px no-repeat,
    linear-gradient(var(--kicker-t02), var(--kicker-t02)) 48px 0 / 5px 5px no-repeat,
    linear-gradient(var(--kicker-t01), var(--kicker-t01)) 54px 0 / 5px 5px no-repeat;
}
/* Meta line — clock + time + middle dot + deliverables. Single-line
   strip in --gray-dark; matches /explore (.free-page#explorePage
   .ep-meta-line) one-for-one. */
.mw-page .ep-meta-line {
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
  margin-top: var(--space-3);
  margin-bottom: var(--space-4);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-normal);
  line-height: 1.4;
  color: var(--ink-2);
}
.mw-page .ep-meta-line .ep-meta-clock {
  width: 12px;
  height: 12px;
  flex: 0 0 auto;
  color: currentColor;
}
.mw-page .ep-meta-line .ep-meta-sep {
  opacity: 0.6;
}
.mw-page .activity-preview-combined { gap: 0; }

/* In-progress preview state */
.mw-inprog-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--space-3);
  padding: 18px var(--space-5);
  box-sizing: border-box;
}
.mw-inprog-state .mw-inprog-headline {
  font-size: var(--text-sm);
  color: var(--ink-2);
  line-height: 1.5;
  font-weight: var(--font-weight-normal);
  margin: 0;
  max-width: 340px;
}
.mw-inprog-state .mw-inprog-action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px var(--space-1);
  background: transparent;
  border: 0;
  color: var(--pink);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
  cursor: pointer;
}
.mw-inprog-state .mw-inprog-action .mw-inprog-label { line-height: 1; }
.mw-inprog-state .mw-inprog-dots {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
.mw-inprog-state .mw-inprog-dots span {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--pink);
  animation: mwInprogDot 1.2s infinite ease-in-out both;
}
.mw-inprog-state .mw-inprog-dots span:nth-child(2) { animation-delay: 0.15s; }
.mw-inprog-state .mw-inprog-dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes mwInprogDot {
  0%, 80%, 100% { opacity: 0.25; transform: scale(0.85); }
  40% { opacity: 1; transform: scale(1); }
}
.mw-inprog-state .mw-inprog-action:hover .mw-inprog-label { text-decoration: underline; }

/* Truncate the preview standfirst at 7 lines */
.mw-page #ep-description {
  display: -webkit-box;
  -webkit-line-clamp: 7;
  line-clamp: 7;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Per-row star toggle: hover-revealed; always visible when starred */
.mw-frow-star {
  background: none;
  border: 0;
  padding: var(--space-1-5);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--gray-mid);
  border-radius: 6px;
  flex-shrink: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 120ms ease, color 120ms ease;
}
.mw-frow-star svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.6;
}
.mw-page .mw-frow:hover .mw-frow-star {
  opacity: 1;
  visibility: visible;
}
.mw-frow-star:hover { color: var(--navy); }
.mw-frow-star.is-starred {
  opacity: 1;
  visibility: visible;
  /* Christine (28 May v3): reverted from yellow→pink gradient
     back to solid brand --pink (#FF00AA) — the gradient didn't
     read well at the icon's small size. */
  color: var(--pink);
}
.mw-frow-star.is-starred svg {
  fill: var(--pink);
  /* Christine (28 May v12): pink stroke restored so the filled
     star carries the same hairline outline as the unstarred state —
     visually reads as a pink star with a pink border (the stroke
     sits slightly proud of the fill at the star's points so the
     icon looks deliberately bordered rather than a flat shape).
     Was `transparent` to suppress an unwanted halo against the
     gradient experiment; on a solid fill the stroke + fill in the
     same colour produces the bordered look Christine wants. */
  stroke: var(--pink);
}

/* Mobile: hide the per-row star toggle entirely. The hover-to-reveal
   pattern doesn't translate to touch, and the persistent filled stars
   on already-favourited rows add noise to the narrow layout. */
@media (max-width: 768px) {
  .mw-frow-star { display: none !important; }
}

/* ---------- Project detail page (work_project.html) ---------- */
.mw-back {
  display: inline-flex; align-items: center; gap: var(--space-1);
  color: var(--ink-2); text-decoration: none;
  font-size: var(--text-sm); margin: var(--space-10) 0 0;
}
.mw-back:hover { color: var(--navy); }
.mw-back + .mw-h1-row { margin-top: var(--space-5); }

.mw-h1-row .badge {
  font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.05em;
  padding: 3px 10px; border-radius: 999px; font-weight: 600;
  background: var(--gray-background); color: var(--ink-2);
}
.mw-h1-row .badge.kit { background: var(--gray-white); color: #0066cc; }
.mw-h1-row .badge.program { background: #fff3e0; color: #b8651a; }

.mw-h1-actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}
.mw-h1-actions .mw-h1-menu-trigger {
  padding: var(--space-1-5);
  border-radius: var(--radius-sm);
  color: var(--gray-mid);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.mw-h1-actions .mw-h1-menu-trigger:hover {
  background: var(--gray-light);
  color: var(--navy);
}
.mw-h1-actions .explore-card-menu-wrap.open .mw-h1-menu-trigger {
  background: var(--gray-light);
  color: var(--navy);
}

.mw-pd {
  display: grid;
  /* fr units split the row AFTER the gap is subtracted, so columns
     never sum past 100% + gap. minmax(0, …) lets each column shrink
     below its intrinsic content width so long file names / chat
     messages don't push the right rail outside the container. */
  grid-template-columns: minmax(0, 65fr) minmax(0, 35fr);
  gap: var(--space-10); align-items: start;
  padding: 30px 0 var(--space-10);
  /* Belt-and-braces: clip any rogue absolutely-positioned child that
     still tries to overflow the 1310px detail container. */
  max-width: 100%;
  min-width: 0;
}
.mw-pd > aside { padding-top: 85px; }

/* Mobile-only memory/settings toggle: the right rail (Memory /
   Instructions / Project files) is hidden by default on phones to
   give the file list the full width. The icon button in the title
   row toggles `.is-open` on the aside, which then renders as a
   full-screen overlay drawer. */
.mw-mobile-settings-btn { display: none; }
.mw-aside-close { display: none; }
@media (max-width: 768px) {
  .mw-mobile-settings-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    background: transparent;
    border: 0.75px solid var(--gray-light);
    border-radius: var(--radius-md);
    color: var(--navy);
    cursor: pointer;
    padding: 0;
  }
  .mw-pd { grid-template-columns: minmax(0, 1fr); }
  .mw-pd > aside { display: none; padding-top: 0; }
  .mw-pd > aside.is-open {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: var(--white);
    overflow-y: auto;
    padding: var(--space-10) var(--space-5) var(--space-5);
  }
  .mw-pd > aside.is-open .mw-aside-close {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: var(--space-3);
    right: var(--space-5);
    width: 36px;
    height: 36px;
    background: transparent;
    border: 0;
    font-size: 28px;
    line-height: 1;
    color: var(--navy);
    cursor: pointer;
    padding: 0;
  }
}

/* Published-files note on project-inner — shown above the file list
   when the project contains at least one read-only published file.
   Uses the same muted text token as panel feet for visual parity. */
.mw-pd .mw-published-note {
  margin: 0 0 12px 0;
  padding: 10px 24px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-2);
  background: var(--gray-background);
  border-radius: var(--ew-search-radius, 8px);
}
/* Memory + Instructions panels (right column on project detail):
   white card with the explore-work preview drop shadow instead of the
   default 1px gray border. Scoped to .mw-pd so other .mw-panel uses
   (kit detail, etc.) keep the bordered look. */
.mw-pd > aside .mw-panel {
  background: var(--white);
  border: none;
  box-shadow: var(--ew-preview-section-shadow);
}

.mw-listhdr {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-1) 0 var(--space-2);
  border-bottom: 1px solid var(--gray-light);
}
.mw-listhdr h3 {
  font-size: var(--text-sm); font-weight: 600; margin: 0;
  color: var(--ink-2); text-transform: uppercase; letter-spacing: 0.05em;
}
.mw-listhdr h3 .count { color: var(--gray-mid); font-weight: 400; margin-left: var(--space-2); }
.mw-listhdr-actions { display: flex; gap: var(--space-2); align-items: center; }

.mw-icon-btn {
  width: 30px; height: 30px; border-radius: var(--radius-sm);
  border: 0; background: transparent; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.mw-icon-btn:hover { background: var(--gray-light); }
.mw-icon-btn svg { width: 16px; height: 16px; stroke: var(--ink-2); fill: none; stroke-width: 1.7; }

.mw-sort-btn {
  background: none; border: 0; font-size: var(--text-xs);
  color: var(--ink-2); cursor: pointer;
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
  font-family: inherit;
}
.mw-sort-btn:hover { background: var(--gray-light); }

.mw-frow {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) 16px;
  margin: 0 calc(var(--space-3) * -1);
  border-bottom: 1px solid var(--gray-light);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background 120ms ease;
  text-decoration: none; color: inherit;
}
.mw-frow:hover { background: var(--gray-light); }
.mw-frow-body { flex: 1; min-width: 0; }
.mw-frow-label {
  font-size: var(--text-xs); color: var(--gray-mid);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: var(--space-1);
}
.mw-frow-sep { color: var(--gray-mid); margin: 0 var(--space-1); }
.mw-frow-title { font-size: var(--text-sm); color: var(--navy); font-weight: 500; }
.mw-frow-meta { font-size: var(--text-xs); color: var(--gray-mid); margin-top: 2px; }
.mw-frow-actions { display: flex; gap: var(--space-2); opacity: 0.6; align-items: center; }
.mw-frow:hover .mw-frow-actions { opacity: 1; }

.mw-inprog {
  display: inline-flex; align-items: center; gap: 3px;
  margin-left: var(--space-2); vertical-align: middle;
}
.mw-inprog .dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--pink); animation: mwPulse 1.4s ease-in-out infinite;
}
.mw-inprog .dot:nth-child(2) { animation-delay: 0.2s; }
@keyframes mwPulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }

.mw-panel {
  background: transparent; border: 1px solid var(--gray-light);
  border-radius: var(--radius-md); padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-3);
}
.mw-panel--grouped { padding: 0; }
.mw-panel--grouped .mw-panel-section { padding: var(--space-5); }
.mw-panel--grouped .mw-panel-section + .mw-panel-section {
  border-top: 1px solid var(--gray-light);
}
.mw-panel-foot--spaced { margin-top: var(--space-2); }
.mw-file-upload-hidden { display: none; }
.mw-pf-list { display: flex; flex-direction: column; }
.mw-pf-row .mw-pf-del {
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none; color: var(--ink-2);
  cursor: pointer; padding: 0; border-radius: var(--radius-sm);
  opacity: 0; visibility: hidden; transition: opacity 120ms ease;
}
.mw-pf-row:hover .mw-pf-del { opacity: 1; visibility: visible; }
.mw-pf-row .mw-pf-del:hover { background: var(--gray-light); color: var(--navy); }
.mw-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-2);
}
.mw-panel-head h4 { font-size: var(--text-sm); font-weight: 600; margin: 0; color: var(--navy); }
.mw-panel-head .badge-only {
  font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--gray-mid); background: var(--gray-background);
  padding: 3px var(--space-2); border-radius: 999px;
  display: inline-flex; align-items: center; gap: var(--space-1);
}
.mw-panel-head .edit {
  font-size: var(--text-xs); color: var(--navy); cursor: pointer;
  text-decoration: none; background: none; border: 0; padding: 0; font-family: inherit;
  display: inline-flex; align-items: center;
}
.mw-panel-body {
  font-size: var(--text-sm); color: var(--navy); font-weight: 300; line-height: 1.5;
  white-space: pre-wrap; word-wrap: break-word;
}
.mw-panel-body[contenteditable="true"] {
  outline: 2px solid #0066cc; padding: var(--space-2);
  border-radius: var(--radius-sm); background: var(--off-white);
}
.mw-panel-body.empty { color: var(--navy); font-style: normal; font-weight: 300; }
.mw-panel-foot { font-size: var(--text-xs); color: var(--ink-2); margin-top: var(--space-2); }

.mw-files-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-2);
}
.mw-files-panel-head h4 { font-size: var(--text-sm); font-weight: 600; margin: 0; color: var(--navy); }
.mw-files-panel-head .add {
  font-size: var(--text-lg); color: var(--ink-2); cursor: pointer;
  background: none; border: 0; padding: var(--space-1) var(--space-2);
}

.mw-fim-expand {
  margin-top: var(--space-3); border-top: 1px solid var(--gray-light); padding-top: var(--space-2);
}
.mw-fim-expand summary {
  list-style: none; cursor: pointer; display: flex;
  align-items: center; justify-content: space-between;
  font-size: var(--text-xs); color: #0066cc; font-weight: 500; padding: var(--space-1) 0;
}
.mw-fim-expand summary::-webkit-details-marker { display: none; }
.mw-fim-expand summary .chev { transition: transform 0.15s; font-size: 10px; }
.mw-fim-expand[open] summary .chev { transform: rotate(180deg); }
.mw-fim-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3); margin-top: var(--space-3);
}
.mw-fim-tile {
  position: relative;
  border: 1px solid var(--gray-light); border-radius: var(--radius-lg);
  background: var(--white);
  width: 100%; aspect-ratio: 1 / 1;
  padding: var(--space-3);
  display: flex; align-items: center; justify-content: center;
  text-align: center;
  min-width: 0;
}
.mw-fim-tile-name {
  font-size: var(--text-xs); font-weight: 500; color: var(--navy);
  line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; word-break: break-word;
}
.mw-fim-tile-ext {
  position: absolute; bottom: 6px; left: 6px;
  font-size: 9px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--navy);
  background: var(--white);
  padding: 1px 5px; border-radius: var(--radius-xs);
  border: 1px solid var(--gray-light);
}
.mw-fim-tile-menu {
  position: absolute; top: var(--space-1); right: var(--space-1);
  z-index: 2;
}
.mw-fim-tile-menu .explore-card-menu-trigger {
  color: var(--ink-2);
}
.mw-fim-tile-menu .explore-card-menu-trigger:hover {
  color: var(--navy);
}

.mw-empty {
  padding: var(--space-8) var(--space-6); text-align: center;
  color: var(--gray-mid); font-size: var(--text-sm);
  border: 1px dashed var(--gray-light); border-radius: var(--radius-md);
  margin-top: var(--space-3);
}

.mw-toast {
  position: fixed; bottom: var(--space-6); left: 50%; transform: translateX(-50%);
  background: var(--navy); color: var(--white);
  padding: var(--space-2) var(--space-5); border-radius: var(--radius-sm);
  font-size: var(--text-sm); opacity: 0; transition: opacity 0.2s;
  pointer-events: none; z-index: 200;
}
.mw-toast.show { opacity: 1; }

body:has(.mw-page) .main-content,
body:has(.mw-page) .page-content {
  background: transparent;
}

/* Structural alignment with /free + /explore: when a .listing-hero
   panel is mounted inside .page-content, zero the wrapper's 48px top
   padding so the panel sits flush at the .v2-app top — exactly like
   /free + /explore which live in base-app.html (no .page-content
   wrapper). With the wrapper neutralised, the panel's own
   var(--listing-hero-pad-top) padding produces the IDENTICAL heading
   position as /free, with no calc and no body-class scoping needed.

   The :has() selector auto-fires on every work-section index page
   (/work, /work/projects, /work/library, /program) — they all now
   use the same .listing-hero panel structure, so this single rule
   governs heading position across all four. Detail pages
   (.mw-page--detail at /work/p/<id> and /work/k/<id>) don't render
   .listing-hero, so the rule stays dormant there and they keep
   their compact .mw-h1-row styling. */
body.v2-app .page-content:has(> .mw-page:has(> .listing-hero, > #mw-tab-content > .listing-hero)) {
  padding-top: 0;
}

/* Mobile: collapse the global .page-content 48px gutter on /work
   pages — .mw-page's own 24px L/R padding is the single source of
   horizontal gutter on phones. Without this override the wrapper
   added 48px on top, double-padding the layout. */
@media (max-width: 768px) {
  body:has(.mw-page) .page-content {
    padding-left: 0;
    padding-right: 0;
  }
}

/* Preview card surface — flat white at rest and on hover, matching
   the /free preview pane (single white slab, no shaded inner card). */
.mw-page .activity-preview-section,
.mw-page .activity-preview-section:hover {
  background: var(--white);
  box-shadow: none;
}


/* ===== Kit in-project view: numbered cards strip + preview pane ===== */

.mw-page--kit .mw-pd { /* same 2-col layout as work_project */ }

.mw-kit-progress {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: var(--space-3) 0 var(--space-4);
}
.mw-kit-progress-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  font-size: var(--text-sm);
  color: var(--ink-2);
  flex-wrap: wrap;
}
.mw-kit-progress-meta strong { color: var(--navy); font-weight: var(--font-weight-semibold); }
.mw-kit-progress-now { color: var(--gray-mid); font-size: var(--text-xs); }
.mw-kit-progress-done { color: var(--success); font-weight: var(--font-weight-semibold); }
.mw-kit-progress-bar {
  width: 100%;
  height: 4px;
  background: var(--gray-light);
  border-radius: 999px;
  overflow: hidden;
}
.mw-kit-progress-bar > span {
  display: block;
  height: 100%;
  background: var(--gradient-horizontal);
  transition: width 240ms ease;
}

.mw-kit-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.mw-kit-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-4);
  border: 1px solid var(--gray-light);
  border-radius: 14px;
  background: var(--white);
  cursor: pointer;
  transition: box-shadow 150ms ease, border-color 150ms ease, transform 150ms ease, background 150ms ease;
  outline: none;
  min-height: 132px;
  /* The card root is now <a> when unlocked so the browser can navigate
     natively. Strip default anchor styling so the card looks identical
     whether it's an <a> or a <div>. */
  text-decoration: none;
  color: inherit;
}
a.mw-kit-card:hover,
a.mw-kit-card:focus,
a.mw-kit-card:visited { color: inherit; text-decoration: none; }
.mw-kit-card:hover {
  border-color: var(--navy);
  box-shadow: 0 6px 22px rgba(0,0,0,0.08);
}
.mw-kit-card:focus-visible {
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(0,0,0,0.1);
}

.mw-kit-card-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--gray-light);
  color: var(--gray-mid);
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--gray-light);
}
.mw-kit-card-num svg { width: 18px; height: 18px; }
.mw-kit-card-body { display: flex; flex-direction: column; gap: 2px; }
.mw-kit-card-title {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--navy);
  line-height: 1.3;
}
.mw-kit-card-status {
  font-size: var(--text-xs);
  color: var(--gray-mid);
  line-height: 1.3;
}

/* Active state — current step */
.mw-kit-card.is-active {
  border-color: var(--navy);
  background: var(--white);
  box-shadow: 0 6px 24px rgba(0,0,0,0.08);
}
.mw-kit-card.is-active .mw-kit-card-num {
  background: var(--navy);
  color: var(--white);
  border-color: var(--navy);
}
.mw-kit-card.is-active .mw-kit-card-status {
  color: var(--navy);
  font-weight: var(--font-weight-semibold);
}

/* Complete state — done, click to revisit */
.mw-kit-card.is-complete .mw-kit-card-num {
  background: var(--success);
  color: var(--white);
  border-color: var(--success);
}
.mw-kit-card.is-complete .mw-kit-card-status { color: var(--success); }

/* Locked state — sequential gating */
.mw-kit-card.is-locked {
  cursor: not-allowed;
  background: var(--gray-light);
  opacity: 0.65;
}
.mw-kit-card.is-locked:hover {
  border-color: var(--gray-light);
  box-shadow: none;
}
.mw-kit-card.is-locked .mw-kit-card-num {
  background: transparent;
  color: var(--gray-mid);
}
.mw-kit-card.is-locked .mw-kit-card-title { color: var(--gray-mid); }

/* Preview pane sits below the cards strip, full width of the left column. */
.mw-kit-preview {
  margin-top: var(--space-2);
  margin-bottom: var(--space-6);
}
.mw-kit-preview .activity-preview-panel {
  border: 0.75px solid var(--gray-light);
  border-radius: var(--radius-lg);
  background: var(--white);
  padding: var(--space-5);
  min-height: 180px;
  box-shadow: var(--shadow-sm);
}
.mw-kit-preview .activity-preview-panel .activity-preview-combined {
  padding: 0;
}
.mw-kit-preview .ep-empty {
  color: var(--gray-mid);
  font-size: var(--text-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 140px;
}

.mw-kit-empty {
  grid-column: 1 / -1;
}

/* Preview pane lives at the top of the right aside in kit view. */
.mw-page--kit aside .mw-kit-preview {
  margin-top: 0;
  margin-bottom: var(--space-4);
  position: sticky;
  top: var(--space-4);
}
.mw-page--kit aside .mw-kit-preview .activity-preview-panel {
  padding: var(--space-5);
  min-height: 140px;
}
.mw-page--kit aside .mw-kit-preview .ep-empty { min-height: 100px; }

/* ============================================================
   Modal system v2 — Tier B (Functional) + Tier C (Destructive)
   Targets all .mw-modal-card descendants of .mw-modal-overlay:
   mwEditModal (Tier B), mwConfirmModal (Tier C — red button via
   the existing .btn-danger override below), and kitConfirmModal
   (gets Tier B chrome — gradient stripe + pink primary; will be
   migrated to true Tier A with markup restructure in a follow-up).
   May 8 2026, Christine.
   ============================================================ */
/* ──────────────────────────────────────────────────────────────
   CANONICAL TIER B CHROME — applied to EVERY .mw-modal-card under
   .mw-modal-overlay. No allow-lists, no per-modal overrides.
   Source of truth: tokens/modals.css (--ta-* + --tb-* roles) and
   the v2 mockup (static/galleries/_mockups/tier-b-functional-v2.html).
   May 9 2026, Christine.
   ────────────────────────────────────────────────────────────── */
.mw-modal-overlay .mw-modal-card {
  position: relative;
  overflow: hidden;
  width: 100%;
  max-width: var(--ta-modal-max-width, 440px);
  padding: 0;
  gap: 0;
  border-radius: 0 0 var(--ta-modal-radius-bottom, 16px) var(--ta-modal-radius-bottom, 16px);
  box-shadow: var(--tb-card-shadow, none);
}
.mw-modal-overlay .mw-modal-card.mw-move-card {
  max-width: var(--tb-modal-wide-max-width, 560px);
}
.mw-modal-overlay .mw-modal-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: var(--tb-stripe-height, 3px);
  background: var(--tb-stripe-bg);
}

/* Close (X) — used by Move/Add-people/Quick-action/Program-access */
.mw-modal-overlay .mw-modal-close {
  top: var(--tb-close-inset, 14px);
  right: var(--tb-close-inset, 14px);
  width: var(--tb-close-size, 28px);
  height: var(--tb-close-size, 28px);
  border-radius: var(--tb-close-radius, 6px);
  color: var(--tb-close-color);
}
.mw-modal-overlay .mw-modal-close:hover { background: var(--tb-close-hover-bg); }

/* Heading */
.mw-modal-overlay .mw-modal-title {
  margin: 0;
  padding: var(--ta-head-pad-y, 22px) var(--ta-modal-pad-x, 28px) 0;
  font-size: var(--ta-heading-size);
  font-weight: var(--ta-heading-weight);
  color: var(--tb-heading-color);
  letter-spacing: var(--tb-heading-letter-spacing, -0.01em);
  line-height: var(--tb-heading-line-height, normal);
}
/* Subtitle (sentence under heading) */
.mw-modal-overlay .mw-modal-subtitle {
  margin: 0;
  padding: var(--tb-label-gap, 6px) var(--ta-modal-pad-x, 28px) 0;
  font-size: var(--ta-subheading-size);
  font-weight: var(--ta-subheading-weight);
  color: var(--ta-subheading-color);
  line-height: var(--tb-subtitle-line-height, 1.45);
}
.mw-modal-overlay .mw-modal-subtitle:empty { display: none; }

/* Form field */
.mw-modal-overlay .mw-modal-field {
  margin: 0 0 var(--tb-gap-between-fields, 24px) 0;
  padding: 0 var(--ta-modal-pad-x, 28px);
}
.mw-modal-overlay .mw-modal-field:first-of-type { margin-top: var(--tb-gap-head-to-body, 32px); }
.mw-modal-overlay .mw-modal-field:last-of-type  { margin-bottom: var(--tb-gap-body-to-foot, 24px); }
.mw-modal-overlay .mw-modal-label {
  display: block;
  margin-bottom: var(--tb-label-gap, 6px);
  font-size: var(--tb-label-size);
  font-weight: var(--tb-label-weight);
  color: var(--tb-label-color);
  line-height: var(--tb-label-line-height, normal);
}
.mw-modal-overlay .mw-modal-required { color: var(--tb-input-focus-border); }

.mw-modal-overlay .mw-modal-input,
.mw-modal-overlay .mw-modal-textarea {
  width: 100%;
  font-family: var(--font-family) !important;            /* beat global input rule */
  font-size: var(--tb-input-size) !important;            /* beat @media (max-width:768px) input{font-size:16px!important} */
  font-weight: var(--tb-input-weight, 400) !important;   /* beat typography.css input{font-weight:300} */
  line-height: var(--tb-input-line-height, 1.55);
  padding: var(--tb-input-pad-y) var(--tb-input-pad-x);
  border: 1px solid var(--tb-input-border);
  border-radius: var(--tb-input-radius);
  color: var(--tb-input-color);
  background: var(--tb-input-bg);
}
.mw-modal-overlay .mw-modal-input:focus,
.mw-modal-overlay .mw-modal-textarea:focus {
  outline: none;
  border-color: var(--tb-input-focus-border);
  box-shadow: 0 0 0 var(--tb-input-focus-ring-width, 3px) var(--tb-input-focus-ring);
}
.mw-modal-overlay .mw-modal-textarea {
  min-height: var(--tb-textarea-min-h, 64px);
  resize: vertical;
}

/* Actions (footer) */
.mw-modal-overlay .mw-modal-actions {
  margin-top: 0;
  padding: var(--ta-foot-pad-top, 18px) var(--ta-modal-pad-x, 28px) var(--ta-foot-pad-bottom, 24px);
  gap: var(--ta-foot-gap, 10px);
}

/* Cancel (secondary) — white pill */
.mw-modal-overlay .mw-modal-btn--cancel {
  background: var(--ta-cta-secondary-bg);
  color: var(--ta-cta-secondary-color);
  border: 1px solid var(--ta-cta-secondary-border);
  border-radius: var(--ta-cta-radius, 999px);
  padding: var(--ta-cta-pad-y, 11px) var(--ta-cta-pad-x, 22px);
  font-size: var(--ta-cta-secondary-size);
  font-weight: var(--ta-cta-secondary-weight);
}
.mw-modal-overlay .mw-modal-btn--cancel:hover {
  background: var(--tb-cta-secondary-hover-bg, var(--gray-white));
  border-color: var(--tb-cta-secondary-hover-border, var(--ink-2));
}

/* Save (primary) — pink pill */
.mw-modal-overlay .mw-modal-btn--save {
  background: var(--ta-cta-feature-bg);
  color: var(--ta-cta-feature-color);
  border: 0;
  border-radius: var(--ta-cta-radius, 999px);
  padding: var(--ta-cta-pad-y, 11px) var(--ta-cta-pad-x, 22px);
  font-size: var(--ta-cta-feature-size);
  font-weight: var(--ta-cta-feature-weight);
}
.mw-modal-overlay .mw-modal-btn--save:hover {
  background: var(--tb-cta-feature-hover-bg);
  opacity: 1;
}

/* Tier C — destructive (red pill) */
.mw-modal-overlay .mw-modal-actions .btn-danger {
  background: #DC2626;
  border-color: #DC2626;
  color: var(--white);
  border-radius: var(--ta-cta-radius, 999px);
  padding: var(--ta-cta-pad-y, 11px) var(--ta-cta-pad-x, 22px);
  font-weight: var(--ta-cta-feature-weight);
}
.mw-modal-overlay .mw-modal-actions .btn-danger:hover {
  background: #B91C1C;
  border-color: #B91C1C;
  opacity: 1;
}

/* List variant (Move / Quick-action) */
.mw-modal-overlay .mw-move-list-wrap {
  margin: var(--tb-gap-head-to-body, 32px) var(--ta-modal-pad-x, 28px) var(--tb-gap-body-to-foot, 24px);
  border: 1px solid var(--tb-list-wrap-border);
  border-radius: var(--tb-list-wrap-radius, 14px);
}
.mw-modal-overlay .mw-move-search-row {
  gap: var(--tb-list-row-gap, 12px);
  padding: var(--tb-list-row-pad-y, 12px) var(--tb-list-row-pad-x, 14px);
  border-bottom: 1px solid var(--tb-list-wrap-border);
}
.mw-modal-overlay .mw-move-search-row svg {
  width: var(--tb-list-icon-size, 18px);
  height: var(--tb-list-icon-size, 18px);
  color: var(--tb-close-color);
}
.mw-modal-overlay .mw-move-search {
  font-family: var(--font-family) !important;
  font-size: var(--tb-input-size) !important;
  font-weight: var(--tb-input-weight, 400) !important;
  color: var(--tb-input-color);
}
.mw-modal-overlay .mw-move-search::placeholder { color: var(--gray-mid); }
.mw-modal-overlay .mw-move-list {
  max-height: var(--tb-list-max-h, 340px);
  padding: var(--tb-list-pad, 6px);
}
.mw-modal-overlay .mw-move-item {
  gap: var(--tb-list-row-gap, 12px);
  padding: var(--tb-list-item-pad-y, 8px) var(--tb-list-item-pad-x, 12px);
  border-radius: var(--tb-list-item-radius, 8px);
  font-size: var(--tb-input-size);
  color: var(--tb-input-color);
}
.mw-modal-overlay .mw-move-item:hover,
.mw-modal-overlay .mw-move-item.active { background: var(--tb-list-item-hover-bg); }
.mw-modal-overlay .mw-move-item svg {
  width: var(--tb-list-icon-size, 18px);
  height: var(--tb-list-icon-size, 18px);
}

/* ── Tier B form utilities ────────────────────────────────────────────
   Shared classes that replace the inline-style noise scattered across
   admin/platform/partner modals. Every value flows from a --tb-* / --ta-*
   token so font-size, color and spacing stay in lock-step with the rest
   of the Tier B shell. */

/* Two-column field grid (replaces inline `display:grid;
   grid-template-columns:1fr 1fr; gap:12px;` patterns). Apply on the
   .mw-modal-field wrapper. */
.mw-modal-overlay .mw-modal-grid-2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--tb-grid-col-gap, 12px);
}

/* Inline helper text under an input (replaces inline `font-size:12px;
   color:var(--gray-mid); margin-top:4px;` and similar). */
.mw-modal-overlay .mw-modal-help {
  margin: var(--tb-label-gap, 6px) 0 0;
  font-size: var(--tb-helper-size, 12px);
  font-weight: var(--tb-helper-weight, 400);
  color: var(--tb-helper-color, var(--gray-mid));
  line-height: var(--tb-helper-line-height, 1.45);
}

/* Inline error block (replaces inline `display:none;color:#d32f2f;
   font-size:13px;padding:8px 12px;background:#ffeef0;border-radius:6px;`
   patterns). Hidden by default; toggle with .is-visible or remove
   `hidden` attr from JS. */
.mw-modal-overlay .mw-modal-error {
  display: none;
  margin: var(--tb-gap-between-fields, 24px) var(--ta-modal-pad-x, 28px) 0;
  padding: var(--tb-error-pad-y, 8px) var(--tb-error-pad-x, 12px);
  border-radius: var(--tb-error-radius, 8px);
  background: var(--tb-error-bg);
  color: var(--tb-error-color);
  font-size: var(--tb-error-size, 13px);
  line-height: var(--tb-helper-line-height, 1.45);
}
.mw-modal-overlay .mw-modal-error.is-visible,
.mw-modal-overlay .mw-modal-error[data-visible="true"] {
  display: block;
}

/* "(optional)" qualifier next to a label — same color as helper text. */
.mw-modal-overlay .mw-modal-optional {
  font-weight: 400;
  color: var(--tb-helper-color, var(--gray-mid));
}

/* kitConfirmModal uses generic .btn-primary / .btn-secondary global
   classes, not .ta-btn--*. Beat the global button rules by scoping
   to the modal ID, but consume the canonical --ta-cta-* tokens so
   primary/secondary font-size, weight, padding and radius stay in
   lock-step with every other Tier A / Tier B modal. */
#kitConfirmModal .btn-primary {
  background: var(--ta-cta-feature-bg);
  color: var(--ta-cta-feature-color);
  border: 0;
  border-radius: var(--ta-cta-radius, 999px);
  padding: var(--ta-cta-pad-y, 11px) var(--ta-cta-pad-x, 22px);
  min-height: var(--ta-cta-min-height, 40px);
  font-size: var(--ta-cta-feature-size);
  font-weight: var(--ta-cta-feature-weight);
  box-shadow: none;
}
#kitConfirmModal .btn-primary:hover {
  background: var(--tb-cta-feature-hover-bg);
  opacity: 1;
}
#kitConfirmModal .btn-secondary {
  background: var(--ta-cta-secondary-bg);
  color: var(--ta-cta-secondary-color);
  border: 1px solid var(--ta-cta-secondary-border);
  border-radius: var(--ta-cta-radius, 999px);
  padding: var(--ta-cta-pad-y, 11px) var(--ta-cta-pad-x, 22px);
  min-height: var(--ta-cta-min-height, 40px);
  font-size: var(--ta-cta-secondary-size);
  font-weight: var(--ta-cta-secondary-weight);
}
#kitConfirmModal .btn-secondary:hover {
  background: var(--tb-cta-secondary-hover-bg, var(--gray-white));
  border-color: var(--tb-cta-secondary-hover-border, var(--navy));
}

/* mwEditModal Tier B chrome is now supplied by the canonical
   .mw-modal-overlay rules above. No per-modal block needed. */

/* ============================================================
   mwRenameModal — Tier B tokenized
   Markup: card > h3 + input + actions(.btn-secondary/.btn-primary)
   May 8 2026, Christine.
   ============================================================ */
#mwRenameModal .mw-modal-card {
  width: 100%;
  max-width: var(--ta-modal-max-width, 440px);
  padding: 0;
  gap: 0;
  border-radius: 0 0 var(--ta-modal-radius-bottom, 16px) var(--ta-modal-radius-bottom, 16px);
  box-shadow: var(--tb-card-shadow, none);
  overflow: hidden;
}
#mwRenameModal .mw-modal-card::before {
  height: var(--tb-stripe-height, 3px);
  background: var(--tb-stripe-bg);
}
#mwRenameModal .mw-modal-title {
  margin: 0;
  padding: var(--ta-head-pad-y, 22px) var(--ta-modal-pad-x, 28px) 0;
  font-size: var(--ta-heading-size);
  font-weight: var(--ta-heading-weight);
  color: var(--tb-heading-color);
  letter-spacing: var(--tb-heading-letter-spacing, -0.01em);
  line-height: var(--tb-heading-line-height, normal);
}
#mwRenameModal .mw-modal-input {
  width: calc(100% - (var(--ta-modal-pad-x, 28px) * 2));
  margin: var(--tb-gap-head-to-body, 32px) var(--ta-modal-pad-x, 28px) var(--tb-gap-body-to-foot, 24px);
  font-family: var(--font-family) !important;            /* beat global input rule */
  font-size: var(--tb-input-size) !important;            /* beat @media (max-width:768px) input{font-size:16px!important} */
  font-weight: var(--tb-input-weight, 400) !important;   /* beat typography.css input{font-weight:300} */
  line-height: var(--tb-input-line-height, 1.55);
  padding: var(--tb-input-pad-y) var(--tb-input-pad-x);
  border: 1px solid var(--tb-input-border);
  border-radius: var(--tb-input-radius);
  color: var(--tb-input-color);
  background: var(--tb-input-bg);
}
#mwRenameModal .mw-modal-input:focus {
  outline: none;
  border-color: var(--tb-input-focus-border);
  box-shadow: 0 0 0 var(--tb-input-focus-ring-width, 3px) var(--tb-input-focus-ring);
}
#mwRenameModal .mw-modal-actions {
  margin-top: 0;
  padding: var(--ta-foot-pad-top, 18px) var(--ta-modal-pad-x, 28px) var(--ta-foot-pad-bottom, 24px);
  gap: var(--ta-foot-gap, 10px);
}
#mwRenameModal .btn-secondary {
  background: var(--ta-cta-secondary-bg);
  color: var(--ta-cta-secondary-color);
  border: 1px solid var(--ta-cta-secondary-border);
  border-radius: var(--ta-cta-radius, 999px);
  padding: var(--ta-cta-pad-y, 11px) var(--ta-cta-pad-x, 22px);
  font-size: var(--ta-cta-secondary-size);
  font-weight: var(--ta-cta-secondary-weight);
}
#mwRenameModal .btn-secondary:hover {
  background: var(--tb-cta-secondary-hover-bg);
  border-color: var(--tb-cta-secondary-hover-border);
}
#mwRenameModal .btn-primary {
  background: var(--ta-cta-feature-bg);
  color: var(--ta-cta-feature-color);
  border: 0;
  border-radius: var(--ta-cta-radius, 999px);
  padding: var(--ta-cta-pad-y, 11px) var(--ta-cta-pad-x, 22px);
  font-size: var(--ta-cta-feature-size);
  font-weight: var(--ta-cta-feature-weight);
}
#mwRenameModal .btn-primary:hover {
  background: var(--tb-cta-feature-hover-bg);
  opacity: 1;
}

/* mwMoveModal + list-variant chrome (close, subtitle, list-wrap,
   search row, items) is supplied by the canonical .mw-modal-overlay
   rules above. No per-modal block needed. */

/* ============================================================
   Confirm modal (mwConfirmModal) — Tier C tokenized
   Consumes --tc-* role tokens + --ta-* shared layout tokens
   from static/css/tokens/modals.css to match the canonical
   Tier C v2 mockup template
   (static/galleries/_mockups/tier-c-destructive-v2.html).
   May 8 2026, Christine.
   ============================================================ */
#mwConfirmModal .mw-confirm-card {
  width: 100%;
  max-width: var(--ta-modal-max-width, 440px);
  padding: 0;
  gap: 0;
  border-radius: 0 0 var(--ta-modal-radius-bottom, 16px) var(--ta-modal-radius-bottom, 16px);
  box-shadow: var(--tc-card-shadow, none);
  overflow: hidden;
}
#mwConfirmModal .mw-confirm-head {
  padding: var(--ta-head-pad-y, 22px) var(--ta-modal-pad-x, 28px) 4px;
}
#mwConfirmModal .mw-confirm-card .mw-modal-title {
  /* padding:0 — the wrapping `.mw-confirm-head` already owns the
     head inset; the canonical `.mw-modal-overlay .mw-modal-title`
     padding would otherwise stack on top and shove the heading
     inward (reads as centered). Same fix as `.mw-info-card`. */
  margin: 0;
  padding: 0;
  text-align: left;
  font-size: var(--tc-heading-size);
  font-weight: var(--tc-heading-weight);
  color: var(--tc-heading-color);
  letter-spacing: var(--tc-heading-letter-spacing);
  line-height: var(--tc-heading-line-height, normal);
}
#mwConfirmModal .mw-confirm-sub {
  margin: var(--tc-sub-gap) 0 0;
  text-align: left;
  font-size: var(--tc-subheading-size);
  font-weight: var(--tc-subheading-weight);
  color: var(--tc-subheading-color);
  line-height: var(--tc-subheading-line-height, normal);
}
#mwConfirmModal .mw-confirm-body-wrap {
  padding: var(--tc-body-pad-top) var(--ta-modal-pad-x, 28px) var(--ta-body-pad-bottom, 8px);
}
#mwConfirmModal .mw-confirm-body {
  margin: 0;
  font-size: var(--tc-paragraph-size);
  line-height: var(--tc-paragraph-line-height, 1.6);
  color: var(--tc-paragraph-color);
  font-weight: var(--tc-paragraph-weight);
}
#mwConfirmModal .mw-confirm-body strong {
  color: var(--tc-paragraph-color);
  font-weight: 600;
}
#mwConfirmModal .mw-confirm-callout {
  margin-top: var(--tc-callout-gap);
  background: var(--tc-callout-bg);
  color: var(--tc-callout-color);
  padding: var(--tc-callout-pad-y) var(--tc-callout-pad-x);
  border-radius: var(--tc-callout-radius);
  font-size: var(--tc-callout-size);
  font-weight: var(--tc-callout-weight);
}
#mwConfirmModal .mw-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--ta-foot-gap, 10px);
  padding: var(--ta-foot-pad-top, 18px) var(--ta-modal-pad-x, 28px) var(--ta-foot-pad-bottom, 24px);
  margin-top: var(--tc-foot-margin-top);
}
#mwConfirmModal .mw-modal-actions .btn-secondary {
  appearance: none;
  font-family: inherit;
  padding: var(--ta-cta-pad-y, 11px) var(--ta-cta-pad-x, 22px);
  border-radius: var(--ta-cta-radius, 999px);
  background: var(--tc-cta-secondary-bg);
  color: var(--tc-cta-secondary-color);
  border: 1px solid var(--tc-cta-secondary-border);
  font-size: var(--tc-cta-secondary-size);
  font-weight: var(--tc-cta-secondary-weight);
  cursor: pointer;
}
#mwConfirmModal .mw-modal-actions .btn-danger {
  appearance: none;
  font-family: inherit;
  padding: var(--ta-cta-pad-y, 11px) var(--ta-cta-pad-x, 22px);
  border-radius: var(--ta-cta-radius, 999px);
  background: var(--tc-cta-feature-bg);
  color: var(--tc-cta-feature-color);
  border: 0;
  font-size: var(--tc-cta-feature-size);
  font-weight: var(--tc-cta-feature-weight);
  cursor: pointer;
  box-shadow: none;
}
#mwConfirmModal .mw-modal-actions .btn-danger:hover {
  background: var(--tc-cta-feature-bg);
  filter: brightness(0.95);
  opacity: 1;
}

/* ============================================================
   GIFT / SHARE MODAL — Tier A live restyle
   ────────────────────────────────────────────────────────────
   Mirrors the canonical v2 spec EXACTLY:
     static/galleries/_mockups/tier-a-gift-share-{choose,gift}-v2.html

   Stack (same for every panel):
     1) GRADIENT STRIP   — only the h2 sits on the gradient
     2) META LINE        — product title, dark grey on white
     3) BODY (optional)  — helper paragraph + form / channels
     4) FOOTER           — pink pill (right) + outline pill (left)

   The live template wraps h2 + product-title in ONE `.access-modal-body`,
   so we paint that wrapper white and let the h2 itself supply the
   gradient (full-width via flush padding). Every value is a Tier A token
   sourced from `static/css/tokens/modals.css` — change a token there and
   every Tier A modal updates in lockstep.
   ============================================================ */

/* SHELL — white card, Tier A radius, scoped overlay. */
#giftShareModal.access-modal-overlay {
  background: rgba(0, 0, 0, 0.55);
}
#giftShareModal .access-modal {
  background: var(--white);
  max-width: var(--ta-modal-max-width, 440px);
  border-radius: var(--ta-modal-radius-top, 16px);
  overflow: hidden;
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.18);
  padding: 0;
}

/* CLOSE — plain × on the gradient, no enclosing pill. */
#giftShareModal .access-modal-close {
  position: absolute;
  top: 14px;
  right: 16px;
  width: auto;
  height: auto;
  background: transparent;
  border: 0;
  border-radius: 0;
  color: var(--white);
  opacity: .85;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}
#giftShareModal .access-modal-close:hover { opacity: 1; color: var(--white); }

/* HEAD WRAPPER — first .access-modal-body holds h2 + product-title.
   Strip its padding so the h2 below can paint the gradient flush, and
   the product-title can sit in its own meta padding on white.
   `!important` is applied to *only* the four structural declarations
   that the legacy dark-modal rules in home-search.css (lines 2797-2817)
   actively fight (background, color, padding). Every value still flows
   from a Tier A token — the !important is a cascade safety belt, not a
   value override. Without it, browser cache + load-order quirks let the
   legacy rules occasionally re-apply gradient + light text to the body
   and meta-line on /explore. */
#giftShareModal .access-modal > .access-modal-body:first-of-type {
  background: var(--white) !important;
  padding: 0 !important;
  text-align: left;
}

/* GRADIENT STRIP — the h2 IS the strip. Token-driven padding/colour. */
#giftShareModal .access-modal h2 {
  margin: 0 !important;
  background: var(--modal-head-bg) !important;
  color: var(--ta-heading-color) !important;
  font-size: var(--ta-heading-size);
  font-weight: var(--ta-heading-weight);
  padding: var(--ta-head-pad-y, 22px) var(--ta-modal-pad-x, 28px) !important;
  line-height: 1.25;
  letter-spacing: -.01em;
}

/* META LINE — product title, dark grey on white, sits below the gradient.
   Same role tokens as `.modal-meta` in the v2 mockup. Uses
   --tb-gap-head-to-body for the gap from the gradient strip so the
   rhythm matches every other Tier B body wrapper (mw-modal, etc.). */
#giftShareModal .access-modal-report-title {
  margin: 0 !important;
  padding: var(--tb-gap-head-to-body, 32px) var(--ta-modal-pad-x, 28px) 0 !important;
  color: var(--ta-subheading-color) !important;
  font-size: var(--ta-subheading-size);
  font-weight: var(--ta-subheading-weight);
  line-height: normal;
  background: var(--white) !important;
}

/* BODY — helper paragraph + form fields / channel buttons.
   Top padding uses --ta-paragraph-gap so the helper paragraph sits one
   paragraph-rhythm unit below the meta line above it. */
#giftShareModal .gs-panel > .access-modal-body {
  background: var(--white) !important;
  padding: var(--ta-paragraph-gap, 16px) var(--ta-modal-pad-x, 28px) var(--ta-body-pad-bottom, 8px) !important;
  text-align: left;
  color: var(--ta-paragraph-color) !important;
}
#giftShareModal .gs-helper {
  margin: 0;
  color: var(--ta-paragraph-color);
  font-size: var(--ta-paragraph-size);
  font-weight: var(--ta-paragraph-weight);
  line-height: var(--ta-paragraph-line-height, 1.6);
}
#giftShareModal .gs-change-link {
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--tb-link-color);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
#giftShareModal .gs-change-link:hover { opacity: .85; }
#giftShareModal .gs-helper strong {
  color: var(--ta-paragraph-strong-color);
  font-weight: var(--ta-paragraph-strong-weight);
}
/* PRICE ROW — v2 gift-confirmation spec: big bold figure + quiet descriptor.
   All values flow from --ta-price-* tokens (single source of truth). */
#giftShareModal .gs-price-row {
  display: flex;
  align-items: baseline;
  gap: var(--ta-price-row-gap, 8px);
  margin: var(--ta-price-row-margin-top, 18px) 0 var(--ta-price-row-margin-bottom, 4px);
}
#giftShareModal .gs-price {
  font-size: var(--ta-price-size);
  font-weight: var(--ta-price-weight);
  color: var(--ta-price-color);
  letter-spacing: -.02em;
  line-height: 1;
}
#giftShareModal .gs-price-sub {
  font-size: var(--ta-price-byline-size);
  color: var(--ta-price-byline-color);
  font-weight: var(--ta-price-byline-weight);
}
#giftShareModal .gs-sent-title {
  margin: 0 0 var(--ta-paragraph-gap, 16px);
  color: var(--ta-paragraph-strong-color);
  font-weight: var(--ta-paragraph-strong-weight);
  font-size: var(--ta-paragraph-size);
}

/* FORM FIELDS — Tier B form tokens (matches :is(#mwEditModal, #addPeopleOverlay, #programAccessOverlay) field rhythm).
   Helper paragraph → 32px → first field → 24px → next field → 24px →
   price row → footer. Label-to-input gap mirrors --tb-label-gap. */
#giftShareModal .gs-form {
  display: flex;
  flex-direction: column;
  gap: var(--tb-gap-between-fields, 24px);
}
#giftShareModal .gs-form .gs-helper { margin-bottom: calc(var(--tb-gap-head-to-body, 32px) - var(--tb-gap-between-fields, 24px)); }
#giftShareModal .gs-field { display: flex; flex-direction: column; gap: var(--tb-label-gap, 6px); }
#giftShareModal .gs-field-label {
  color: var(--tb-label-color);
  font-size: var(--tb-label-size, 13px);
  font-weight: var(--tb-label-weight, 500);
}
#giftShareModal .gs-field-optional {
  color: var(--gray-mid);
  font-weight: 400;
}
#giftShareModal .gs-input {
  background: var(--tb-input-bg);
  color: var(--tb-input-color, var(--navy));
  border: 1px solid var(--tb-input-border, var(--gray-light));
  border-radius: var(--tb-input-radius, 10px);
  padding: var(--tb-input-pad-y, 11px) var(--tb-input-pad-x, 12px);
  font-size: var(--tb-input-size, 14px);
  font-weight: 400;
  font-family: inherit;
}
#giftShareModal .gs-input:focus {
  outline: none;
  border-color: var(--tb-input-focus-border, var(--navy));
  box-shadow: 0 0 0 3px var(--tb-input-focus-ring, rgba(255, 85, 164, .18));
}
#giftShareModal .gs-error { color: var(--purple); margin: 0; font-size: 13px; }
/* Invalid field highlight — pink border + matching focus ring so the
   user can spot empty / malformed fields after pressing Next. Reuses
   the same Tier B focus tokens for visual consistency.
   Christine, 8 May 2026. */
#giftShareModal .gs-input.is-invalid,
#giftShareModal .gs-input.is-invalid:focus {
  border-color: var(--tb-input-focus-border, var(--navy));
  box-shadow: 0 0 0 3px var(--tb-input-focus-ring, rgba(255, 85, 164, .18));
}

/* CHANNEL BUTTONS — light theme tiles. */
#giftShareModal .gs-channels { display: flex; gap: 10px; }
#giftShareModal .gs-channel {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 14px 8px;
  background: var(--white);
  border: 1px solid var(--gray-light);
  border-radius: 12px;
  color: var(--ink-2);
  font-size: 13px;
  text-decoration: none;
  cursor: pointer;
}
#giftShareModal .gs-channel:hover {
  background: var(--gray-lightest);
  border-color: var(--gray-mid);
}

/* FOOTER — pink pill primary + outline pill secondary. */
#giftShareModal .access-modal-footer {
  background: var(--white);
  padding: var(--ta-foot-pad-top, 18px) var(--ta-modal-pad-x, 28px) var(--ta-foot-pad-bottom, 24px);
}
#giftShareModal .access-modal-buttons,
#giftShareModal .access-modal-buttons-trio {
  display: flex;
  gap: var(--ta-foot-gap, 10px);
  justify-content: flex-end;
}
#giftShareModal .access-modal-cta,
#giftShareModal .access-modal-buttons-trio .access-modal-cta-tier,
#giftShareModal .access-modal-buttons-trio .access-modal-cta-outline {
  flex: var(--ta-cta-flex) !important;
}
#giftShareModal .access-modal-cta {
  appearance: none;
  border: 0;
  font-family: inherit;
  border-radius: var(--ta-cta-radius);
  padding: var(--ta-cta-pad-y) var(--ta-cta-pad-x);
  font-size: var(--ta-cta-feature-size);
  font-weight: var(--ta-cta-feature-weight);
  cursor: pointer;
  text-align: center;
  transition: var(--ta-cta-transition);
}
#giftShareModal .access-modal-cta:hover { transform: translateY(var(--ta-cta-hover-lift)); }
#giftShareModal .access-modal-cta-tier {
  background: var(--ta-cta-feature-bg);
  color: var(--ta-cta-feature-color);
}
#giftShareModal .access-modal-cta-outline {
  background: var(--ta-cta-secondary-bg);
  color: var(--ta-cta-secondary-color);
  border: var(--ta-cta-border-width) solid var(--ta-cta-secondary-border);
  font-size: var(--ta-cta-secondary-size);
  font-weight: var(--ta-cta-secondary-weight);
}

/* SENT + CONFIRMED panels hide the meta line (the gradient/heading
   already carries the message — a credit-balance readout there would
   just be noise). The GIFT panel keeps the Tier A meta line, now
   repurposed as the "You have ## credits available" readout. */
#giftShareModal[data-panel="sent"] .access-modal-report-title,
#giftShareModal[data-panel="confirmed"] .access-modal-report-title {
  display: none !important;
}
/* Personal-note textarea sits tighter under the email field — no
   label heading, just the input. Reduces the inter-field rhythm to a
   smaller token so it visually groups with the email above. */
#giftShareModal .gs-field-note {
  margin-top: calc(var(--tb-label-gap, 6px) - var(--tb-gap-between-fields, 24px));
}

/* ============================================================
   SENT PANEL → Tier B chrome overrides.
   The gift form keeps the Tier A gradient hero (conversion);
   the sent confirmation drops to Tier B (functional): thin
   gradient stripe + dark heading on white card. All values
   flow from --tb-* tokens — no literals.
   May 8 2026, Christine.
   ============================================================ */
#giftShareModal[data-panel="sent"] .access-modal,
#giftShareModal[data-panel="confirmed"] .access-modal {
  position: relative;
}
#giftShareModal[data-panel="sent"] .access-modal::before,
#giftShareModal[data-panel="confirmed"] .access-modal::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: var(--tb-stripe-height, 3px);
  background: var(--tb-stripe-bg);
  z-index: 1;
}
#giftShareModal[data-panel="sent"] .access-modal h2,
#giftShareModal[data-panel="confirmed"] .access-modal h2 {
  background: var(--white) !important;
  color: var(--tb-heading-color) !important;
  /* Secondary-modal scale: smaller + lighter than the canonical
     Tier B heading. Christine, 8 May 2026 — "it's just a secondary
     modal". Tokens fall back gracefully if the secondary scale
     isn't yet defined globally. */
  font-size:   var(--ta-heading-size-secondary, 15px) !important;
  font-weight: var(--ta-heading-weight-secondary, 500) !important;
  letter-spacing: var(--tb-heading-letter-spacing, -0.01em);
  line-height: var(--tb-heading-line-height, normal);
  padding: var(--ta-head-pad-y, 22px) var(--ta-modal-pad-x, 28px) 0 !important;
}
#giftShareModal[data-panel="sent"] .access-modal-close,
#giftShareModal[data-panel="confirmed"] .access-modal-close {
  color: var(--tb-close-color, var(--gray-mid));
}
#giftShareModal[data-panel="sent"] .access-modal-close:hover,
#giftShareModal[data-panel="confirmed"] .access-modal-close:hover {
  color: var(--ink-2);
}
#giftShareModal[data-panel="sent"] .gs-panel[data-gs-panel="sent"] > .access-modal-body,
#giftShareModal[data-panel="confirmed"] .gs-panel[data-gs-panel="confirmed"] > .access-modal-body {
  padding-top: var(--tb-gap-head-to-body, 32px) !important;
}
/* Sent panel rhythm: breathing room between the "you're sending to …"
   line and the channel buttons below it. Uses the shared paragraph-gap
   token so the spacing stays in sync with other Tier B body copy. */
#giftShareModal[data-panel="sent"] .gs-helper {
  margin-bottom: var(--ta-paragraph-gap, 16px);
}

/* ── Confirmed panel — quiet "gift delivered" state.
   The navbar credits pill already updates instantly, so this panel
   doesn't repeat the new balance. Layout: bare brand-pink tick (no
   circle bg) → quiet "manage your gifts" link → standard pill CTA
   (uses .access-modal-cta token, NOT full width). */
#giftShareModal .gs-confirmed-body {
  text-align: center !important;
  padding-top: var(--tb-gap-head-to-body, 32px) !important;
  padding-bottom: var(--ta-body-pad-bottom, 8px) !important;
}
#giftShareModal .gs-confirmed-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto var(--ta-paragraph-gap, 16px);
  background: transparent;
  border: 0;
  color: var(--tb-icon-success-color);
}
#giftShareModal .gs-confirmed-icon svg {
  width: var(--tb-icon-success-size);
  height: var(--tb-icon-success-size);
  stroke-width: var(--tb-icon-success-stroke);
}
#giftShareModal .gs-confirmed-manage {
  margin: 0;
  text-align: center;
}
#giftShareModal .gs-confirmed-manage-link {
  color: var(--ta-helper-color, var(--gray-mid));
  text-decoration: underline;
  text-underline-offset: 2px;
  font-size: var(--ta-helper-size, 13px);
}
#giftShareModal .gs-confirmed-manage-link:hover {
  color: var(--navy);
}

/* SUBLINE — "Subscribe to gift…" beneath the chooser CTAs. */
#giftShareModal .gs-subline {
  margin: var(--ta-subline-margin-top, 16px) 0 0;
  color: var(--ta-subline-color);
  font-size: var(--ta-subline-size);
  line-height: var(--ta-subline-line-height, 1.5);
  text-align: center;
}
#giftShareModal .gs-subline a {
  color: var(--ta-subline-link-color);
  font-weight: var(--ta-subline-link-weight);
  text-decoration: underline;
}

/* ============================================================
   Tier B form-modal additions (May 9 2026):
   - .mw-modal-error: inline field error helper for #programAccessOverlay
     (code/email step errors). Sits inside .mw-modal-field, which already
     carries the horizontal pad token, so we only add a small top gap.
   - #programAccessOverlay step swap: mirrors the gift-share-modal
     data-panel="code|email" pattern so the preview pipeline (which sets
     data-panel via panel_show) and production JS (overlay.dataset.panel)
     share one mechanism. The active step inherits the full Tier B form
     chrome (heading/subtitle/field/actions) from the :is(...) blocks
     above — no per-step duplication needed.
   ============================================================ */
:is(#mwEditModal, #addPeopleOverlay, #programAccessOverlay) .mw-modal-error {
  margin: var(--space-2, 8px) 0 0;
  font-size: var(--text-xs, 12px);
  color: var(--negative);
}
:is(#mwEditModal, #addPeopleOverlay, #programAccessOverlay) .mw-modal-error.hidden {
  display: none;
}

#programAccessOverlay[data-panel="code"] .mw-modal-step[data-panel="email"],
#programAccessOverlay[data-panel="email"] .mw-modal-step[data-panel="code"] {
  display: none;
}

/* ---------------------------------------------------------------- */
/* My Work — Starred tab (leftmost tab in the My Work strip).
   Icon-only variant: the star glyph itself is the affordance —
   no "STARRED" label, matching the pattern used on the public
   navbar (⭐ FOUNDERS EDUCATORS TEAMS …). The icon inherits the
   tab's colour; when the tab is .active, the star fills with
   currentColor to give a clear selected state without needing
   the underline that the labelled tabs use. The underline is
   suppressed on this tab so the star reads as a standalone icon
   rather than a tiny tab. */
/* ---------------------------------------------------------------- */
.mw-tab-starred { display: inline-flex; align-items: center; gap: 6px; }
.mw-tab-starred-icon { display: inline-flex; width: 18px; height: 18px; color: var(--navy); }
.mw-tab-starred-icon svg { width: 18px; height: 18px; display: block; }
.mw-tab-starred.active .mw-tab-starred-icon svg { fill: currentColor; }

/* Icon-only variant overrides — used in the My Work tab strip.

   The star sits in the SAME column as the per-row checkbox below
   (the .mw-select-all-box / .mw-frow-check icons), so the star and
   checkbox stack as one vertical line on the left of the page. The
   sibling tabs ("FILES", "PROJECTS") shift right by the same amount
   via the .home-filter-bar offset further down, so their text aligns
   with the "N file(s)" / "N selected" label in the .mw-info-row
   directly below.

   Geometry (Christine, 28 May):
     • .mw-tabs-row  is max-width 1342px, centered (margin: auto).
     • .mw-info-row  is max-width 1310px, centered (margin: auto).
     • The select-all checkbox sits at .mw-info-row outer-left - 4px
       (it's `left: -4px` of the row's padding box). It is 16px wide
       → its CENTRE is at .mw-info-row outer-left + 4px.

   Because the two rows have different max-widths, the offset
   between their outer-left edges is viewport-dependent:
     • viewport ≥ 1342: each centered → offset = (1342-1310)/2 = 16px
     • viewport ≤ 1310: both rows fill width → offset = 0
     • in between: ramps from 0 → 16px as viewport widens.
   A single fixed `left:` value can't track that, so we anchor the
   star with a calc() that mirrors the browser's auto-centering of
   both rows. Star is 20px wide → subtract 10px so it CENTRES on the
   checkbox-centre x (`outer-left + 4`), then offset by another -10
   to convert centre → left edge ⇒ final addend = -6px. */
.mw-page .free-tabs-row.mw-tabs-row {
  position: relative;
}
.mw-page .free-tabs-row .home-mega-tab:has(> .mw-tab-starred--icon-only) {
  position: absolute;
  left: calc(
    max(0px, (100vw - 1310px) / 2)
    - max(0px, (100vw - 1342px) / 2)
    - 62px
  );
  top: 50%;
  transform: translateY(-50%);
  margin: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
}
/* Push the FILES / PROJECTS tab strip right by exactly the row-width
   delta so the first tab's text starts at the same x as the
   "N file(s)" / "N selected" label in the .mw-info-row below.
   Math is the same as the star calc minus the -6px star centring
   tweak: `(100vw - 1310)/2 - (100vw - 1342)/2` = 16px at wide
   viewports, 0 when both rows fill the viewport. Applied as
   padding-left on .home-filter-bar (the inline container that
   holds the tabs) so the tabs translate together; the absolutely-
   positioned star above is removed from flow and stays anchored
   to the checkbox column independent of this shift. */
.mw-page .free-tabs-row .home-filter-bar {
  padding-left: 0;
}
.mw-page .mw-tab-starred--icon-only {
  gap: 0;
  padding: 0;
  /* Suppress the tab underline (the active ::after on .home-mega-trigger):
     the star's fill state is the only active indicator we want. */
}
.mw-page .mw-tab-starred--icon-only::after,
.mw-page .mw-tab-starred--icon-only.active::after {
  display: none !important;
  content: none !important;
}
.mw-page .mw-tab-starred--icon-only .mw-tab-starred-icon {
  width: 20px;
  height: 20px;
}
.mw-page .mw-tab-starred--icon-only .mw-tab-starred-icon svg {
  width: 20px;
  height: 20px;
}

/* Two-state filter colour scheme (Christine, 28 May).  The icon
   toggles between two resting states; colour alone communicates
   which one is active so the user always knows what they're
   looking at without reading the tooltip:

     • all (idle)  — grey outline
     • starred     — black filled

   `currentColor` flows through to both the SVG stroke and (for
   the starred state) the polygon fill via the inline `fill=
   currentColor` set in the template, so we only need to set
   `color` here.  Tokens come from tokens/colors.css — no hex
   literals. */
.mw-page .mw-tab-starred--icon-only.mw-tab-starred--state-all
  .mw-tab-starred-icon {
  color: var(--gray-mid);
}
.mw-page .mw-tab-starred--icon-only.mw-tab-starred--state-starred
  .mw-tab-starred-icon {
  /* Christine (28 May): pink fill on the active "starred" filter
     tab — mirrors the .mw-frow-star.is-starred row treatment. */
  color: var(--pink);
}

/* ===========================================================================
   My Resources tab (/work/resources)
   ---------------------------------------------------------------------------
   The page reuses /explore's two-column list + preview-pane + holding-ad
   layout (wrapper carries `free-page` + id="explorePage"), so only the
   bespoke resource-row tag, preview description and download button need
   styling here. Scoped to `.mw-res-*` so nothing leaks to the Files /
   Projects tabs.
   ======================================================================== */

/* File-type tag on each list row (e.g. "Excel"). */
.mw-res-type-tag {
  display: inline-block;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: 0.01em;
}
.mw-res-dot {
  margin: 0 6px;
  color: var(--ink-3, #9aa0a6);
}

/* Preview-pane description paragraph. */
.mw-res-prev-desc {
  margin: 0 0 var(--space-6, 24px);
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-secondary, #444);
}

/* Download button in the preview pane. */
.mw-res-download {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 20px;
  border-radius: 999px;
  background: var(--text-primary, #111);
  color: var(--white, #fff);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  border: none;
  cursor: pointer;
  transition: opacity 0.15s ease, transform 0.05s ease;
}
.mw-res-download:hover { opacity: 0.88; }
.mw-res-download:active { transform: translateY(1px); }
.mw-res-download svg { flex: 0 0 auto; }

/* Per-row download icon button — replicates the icon-button look used on the
   Files / Projects rows (.mw-frow-star / .mw-info-icon-btn): gray-mid glyph,
   rounded hit area, darkens against a soft background on hover. Always visible
   since download is this page's primary row action. The .activity-item-actions
   container is already positioned at the row's right edge by home-search.css. */
.mw-res-dl {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-1-5);
  border-radius: 6px;
  color: var(--gray-mid);
  background: none;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  flex-shrink: 0;
  transition: color 120ms ease, background 120ms ease, transform 0.05s ease;
}
.mw-res-dl:hover { color: var(--navy); background: var(--bg-hover); }
.mw-res-dl:active { transform: translateY(1px); }
.mw-res-dl svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.6; }

/* Empty "no search match" line under the list. */
.mw-res-empty-list {
  padding: var(--space-6, 24px) var(--space-4, 16px);
  color: var(--ink-2, #666);
  font-size: 14px;
}
.mw-res-empty-list.hidden { display: none; }

