
:root{
  color-scheme: light;
  /* Brand palette (AMC Brand Guidelines) */
  --amc-black:#2D2926; --amc-citrus:#92D500; --amc-evergreen:#425A3E;
  --amc-fuchsia:#DA1A82; --amc-charcoal:#5B6770; --amc-gray:#A2AAAD;
  --amc-gray-light:#C1C6C8; --amc-sage:#BBC5BA; --amc-white:#FFFFFF;
  /* Semantic tokens (light theme) */
  --bg:#EFF2EF; --surface:#FFFFFF; --surface-2:#F2F5F2; --surface-dark:#2D2926;
  /* P2 section-divider band: a neutral third surface, distinct from both white data rows and the pale
     zebra/header surface. It is deliberately outside every reserved status/highlight hue. */
  --divider-band-surface:#E2E7E2; --divider-band-foreground:#46504B;
  --text:#2D2926; --text-muted:#5B6770; --text-faint:#8A9296; --on-dark:#EDEFEA;
  --border:#DDE3DD; --border-strong:#C1C6C8; --field-border:#A2AAAD; --divider:#E7ECE7;
  --focus:#2D2926; --selected:#92D500; --selected-surface:#F0F7DC; --selected-soft:rgba(45,41,38,.16);
  --primary:#2D2926; --positive:#425A3E; --positive-surface:#EEF6E2; --positive-border:#BBC5BA;
  --destructive:#A8125F; --destructive-surface:#FBEAF3; --destructive-border:#F0C4DD; --destructive-chip:#EBB9D5;
  --warning-surface:#EEF0F2; --disabled:#C1C6C8;
  --chip-surface:#EAEFEA; --chip-border:#DCE1DC;
  /* Non-semantic job highlight palette (jobs-read-model-and-lifecycle.md): distinct from the
     reserved semantic colors green/red-fuchsia/orange/Citrus. */
  --hl-yellow:#F2D54E; --hl-pink:#F2A8CC; --hl-blue:#7FB6F0; --hl-purple:#B79BE0; --hl-cyan:#79D2D2;
  /* Phase 6A operational flag colours (reserved): orange = missed-work carry-forward, red = QC rework.
     DF-009: rework is a TRUER red (#D11A1A), pulled away from the brand fuchsia (--destructive #A8125F) +
     the pink job-highlight family, so a QC re-do reads as urgent and distinct, not "more brand pink". */
  --flag-carry:#E8730C; --flag-rework:#D11A1A;
  /* Jobs-sort week-override PAIR accent (neutral slate — NOT a reserved status hue): visually links a job's
     "Future weeks only" durable solid to its "This week's visit" ghost so they read as one job. */
  --pair-accent:#5B6B8C; --pair-surface:#EEF1F6;
  /* Default to the touch-safe target. Fine-pointer desktop grids opt into the approved compact value. */
  --data-grid-grip-column:44px;
  --radius:11px; --radius-sm:9px; --radius-lg:16px;
  --shadow-pop:0 18px 44px -16px rgba(0,0,0,.4);
  /* DESIGN-001 — cohesive elevation scale + a shared easing curve. Refresh WITHIN the existing
     tokens (no competing design system); reserved semantic colours untouched. --shadow-pop is kept
     for overlays/popovers; -sm/-md add restrained depth to resting/hovered surfaces. */
  --shadow-sm:0 1px 2px rgba(45,41,38,.06), 0 1px 3px -1px rgba(45,41,38,.08);
  --shadow-md:0 4px 10px -3px rgba(45,41,38,.12), 0 2px 5px -2px rgba(45,41,38,.08);
  --ease:cubic-bezier(.2,.65,.25,1);
  /* M-7 (motion-and-continuity-laws.md) — the ONE motion vocabulary. Components and JS helpers
     consume these tokens; no hardcoded durations. A future alternate-motion policy changes these
     tokens/primitives, never individual components (M-8: no separate reduced-motion mode is built;
     the prefers-reduced-motion kill-switch at the end of this sheet remains authoritative). */
  --ease-out:cubic-bezier(.16,.84,.28,1);
  --motion-press:120ms; --motion-settle:160ms; --motion-fade:160ms; --motion-disclose:200ms; --motion-sheet:220ms; --motion-flip:240ms; --motion-flip-lens:1000ms; --motion-flip-sort-entry:1000ms;
}
/* Self-hosted Archivo (OFL), latin subset, served same-origin under the /app-assets/* proxy.
   font-display:swap paints the fallback stack immediately, then swaps to Archivo (no FOIT). */
@font-face{font-family:'Archivo';font-style:normal;font-weight:400;font-display:swap;src:url('/app-assets/fonts/archivo-400.woff2') format('woff2');}
@font-face{font-family:'Archivo';font-style:normal;font-weight:600;font-display:swap;src:url('/app-assets/fonts/archivo-600.woff2') format('woff2');}
@font-face{font-family:'Archivo';font-style:normal;font-weight:700;font-display:swap;src:url('/app-assets/fonts/archivo-700.woff2') format('woff2');}
*{box-sizing:border-box;}
/* The [hidden] attribute is the single source of truth for JS-toggled elements
   (overlays, the location menu, spinners, alerts). Some of those carry a class
   that sets display (flex/inline-block), which would otherwise win over the UA
   [hidden] rule — so make hidden authoritative. */
[hidden]{display:none!important;}
html,body{height:100%;}
body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:'Archivo',system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  -webkit-font-smoothing:antialiased; font-size:16px; line-height:1.5;
}
a{color:inherit;}
button{font-family:inherit;}
::placeholder{color:var(--amc-gray);}
:focus-visible{outline:2px solid var(--focus); outline-offset:2px;}
@keyframes amc-spin{to{transform:rotate(360deg);}}
@keyframes amc-toast{from{opacity:0;transform:translate(-50%,8px);}to{opacity:1;transform:translate(-50%,0);}}
/* NAV-001 "Show in ___ list" — a transient neutral pulse on the row a deep-link scrolled to. Neutral
   (--selected-soft), so it never reads as the Citrus checked state; works on both .amc-jobrow (div) and
   table rows (animating the row + its cells). Removed after it fires so it can re-trigger. */
@keyframes amc-navfocus{0%,55%{background-color:var(--selected-soft);}100%{background-color:transparent;}}
.is-nav-focus{animation:amc-navfocus 2.2s ease-out;}
tr.is-nav-focus>td{animation:amc-navfocus 2.2s ease-out;}
.amc-spin{display:inline-block;width:17px;height:17px;border:2px solid rgba(255,255,255,.45);border-top-color:#fff;border-radius:50%;animation:amc-spin .7s linear infinite;}
/* Machine identifiers (CRM refs, Stripe keys, app ids) have NO break opportunity, so a monospace id is a
   single unbreakable word: in a narrow cell it paints past its box, and visible ink overflow is scrollable
   overflow — which on a phone makes Chromium widen the LAYOUT viewport to fit (KBINSET-001 / MOBILE-VIEWPORT-001
   measured 431px of document in a 390px viewport, innerHeight 844->933). Break anywhere instead. Inert wherever
   an ancestor already owns wrapping via white-space:nowrap (the Jobs config grid cells). */
.amc-mono{font-family:ui-monospace,Menlo,Consolas,monospace;overflow-wrap:anywhere;}
.amc-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}
.amc-eyebrow{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11px;color:var(--text-faint);letter-spacing:.04em;}
.amc-note{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11px;color:var(--text-faint);line-height:1.7;}

/* ---------- auth (unauthenticated) layout ---------- */
.amc-auth-wrap{min-height:100%;display:flex;flex-direction:column;background:var(--bg);}
.amc-auth{width:100%;max-width:480px;margin:0 auto;padding:26px 22px 48px;display:flex;flex-direction:column;gap:18px;}
.amc-auth__head h1{margin:6px 0 0;font-size:26px;font-weight:700;letter-spacing:-.01em;}
.amc-auth__head p{margin:7px 0 0;font-size:15px;color:var(--text-muted);line-height:1.45;}
.amc-form{display:flex;flex-direction:column;gap:16px;}

/* ---------- fields ---------- */
.amc-label{display:block;font-size:13px;font-weight:600;color:var(--text);margin-bottom:7px;}
.amc-optional{font-weight:500;color:var(--amc-gray);}
.amc-field{width:100%;min-height:50px;padding:13px 14px;border:1.5px solid var(--field-border);border-radius:10px;font-size:16px;color:var(--text);background:var(--surface);outline:none;}
/* WebKit 301648: native date appearance can force content-box sizing for percentage widths.
   Use our field styling while retaining the native date/time input and picker. */
.amc-field[type="date"],.amc-field[type="datetime-local"]{-webkit-appearance:none;appearance:none;min-width:0;max-width:100%;box-sizing:border-box;}
.amc-field:focus{border-color:var(--focus);box-shadow:0 0 0 3px rgba(27,27,25,.13);}
.amc-field[readonly]{background:var(--surface-2);color:var(--text-muted);border-color:var(--border);}
.amc-field--code{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:15px;}
.amc-pw{position:relative;display:flex;align-items:center;}
.amc-pw .amc-field{padding-right:78px;}
.amc-pw__toggle{position:absolute;right:7px;min-height:38px;padding:0 12px;border:1px solid var(--border-strong);border-radius:8px;background:#EFF2EF;color:var(--text);font-size:13px;font-weight:600;cursor:pointer;}
.amc-hint{margin-top:7px;font-size:13px;color:var(--text-muted);line-height:1.5;}

/* ---------- buttons ---------- */
.amc-btn{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;min-height:54px;border-radius:var(--radius);border:1.5px solid transparent;font-size:16px;font-weight:600;cursor:pointer;text-decoration:none;}
.amc-btn:disabled{cursor:not-allowed;opacity:1;background:var(--surface-2);color:var(--text-faint);border-color:var(--disabled);box-shadow:none;}
.amc-btn--primary{background:var(--primary);color:#fff;border-color:var(--primary);}
.amc-btn--positive{background:var(--positive);color:#fff;border-color:var(--positive);}
.amc-btn--outline{background:var(--surface);color:var(--text);border-color:var(--field-border);}
.amc-btn--danger{background:var(--surface);color:var(--destructive);border-color:var(--destructive-chip);}
.amc-btn--danger-solid{background:var(--destructive);color:#fff;border-color:var(--destructive);}
.amc-btn:disabled.amc-btn--positive{background:var(--disabled);border-color:var(--disabled);}
.amc-btn--sm{min-height:46px;font-size:14px;padding:0 14px;width:auto;}
.amc-btn--link{background:none;border:none;color:var(--text);font-size:14px;font-weight:600;cursor:pointer;text-decoration:underline;padding:6px 2px;align-self:flex-start;}
/* Standalone shell back-links carry 18px inline margins. The base button's width:100% used to add
   those margins outside a full-width box, making the otherwise clipped canvas 36px scrollable on x. */
.amc-canvas>.amc-btn--link{width:auto;max-width:calc(100% - 36px);}

.amc-divider-top{border-top:1px solid var(--divider);padding-top:16px;display:flex;flex-direction:column;gap:10px;}
.amc-dashed-top{border-top:1px dashed var(--border-strong);padding-top:14px;}

/* ---------- alerts ---------- */
/* Mobile layout-viewport ownership: alerts quote upstream CRM/Stripe sync errors verbatim, which contain
   unbreakable refs. The flex child needs min-width:0 or its min-content width escapes the phone. */
.amc-alert{display:flex;gap:10px;align-items:flex-start;border-radius:var(--radius);padding:13px 14px;font-size:14px;line-height:1.45;overflow-wrap:anywhere;}
.amc-alert>*{min-width:0;}
.amc-alert__glyph{font-weight:700;flex:none;}
.amc-alert--error{background:var(--destructive-surface);border:1px solid var(--destructive-border);color:var(--destructive);}
.amc-alert--info{background:#EFF2EF;border:1px solid #C8CFC8;color:var(--text-muted);}
.amc-alert--success{background:var(--positive-surface);border:1px solid var(--positive-border);color:var(--positive);}
.amc-alert--warn{background:#FBF3E0;border:1px solid #E2B873;color:#8A5A12;}

/* ---------- request-access matching code ---------- */
.amc-code-card{background:var(--surface-dark);color:#fff;border-radius:var(--radius-lg);padding:24px 20px;text-align:center;}
.amc-code-card__hint{font-size:14px;color:var(--amc-gray-light);}
.amc-code-card__code{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:56px;font-weight:700;letter-spacing:.18em;margin:10px 0 6px;padding-left:.18em;}
.amc-pill-countdown{display:inline-flex;align-items:center;gap:7px;background:#3A3633;border:1px solid #4A453F;border-radius:999px;padding:6px 13px;font-size:13px;color:#E8E8E4;}

/* ---------- app shell ---------- */
.amc-app{min-height:100%;display:flex;flex-direction:column;}
.amc-shell{flex:1;min-height:0;display:flex;position:relative;}
.amc-rail{flex:none;background:#F4F7F4;border-right:1px solid var(--divider);display:none;flex-direction:column;padding:14px 10px;gap:3px;width:214px;}
.amc-rail__brand{display:flex;align-items:center;gap:9px;padding:6px 6px 12px;background:none;border:none;cursor:pointer;border-radius:8px;}
.amc-rail__brand img{width:26px;height:26px;border-radius:7px;display:block;flex:none;}
.amc-rail__brand-name{font-size:13.5px;font-weight:700;letter-spacing:.01em;color:var(--text);}
.amc-rail__brand:focus-visible{outline:2px solid var(--selected);}
.amc-navbtn{position:relative;display:flex;align-items:center;gap:10px;width:100%;text-align:left;min-height:42px;padding:8px 11px;border-radius:var(--radius-sm);border:none;background:transparent;color:var(--text);font-size:13.5px;font-weight:600;cursor:pointer;text-decoration:none;}
.amc-navbtn:hover{background:rgba(45,41,38,.05);}
.amc-navbtn.is-active{background:var(--selected);color:var(--amc-black);}
.amc-navbtn__icon{width:22px;height:22px;display:flex;align-items:center;justify-content:center;flex:none;}
.amc-navbtn__icon svg{width:19px;height:19px;}
.amc-navbtn__soon{margin-left:auto;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:9px;letter-spacing:.06em;opacity:.6;}
.amc-navbtn__badge{margin-left:auto;min-width:20px;height:20px;padding:0 6px;border-radius:999px;background:var(--destructive);color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;}
.amc-rail__label{display:inline;}

.amc-main{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0;}
.amc-appbar{flex:none;display:flex;align-items:center;gap:10px;padding:10px 12px;border-bottom:1px solid var(--divider);background:var(--surface);}
.amc-iconbtn{width:44px;height:44px;flex:none;display:flex;align-items:center;justify-content:center;border:1px solid var(--chip-border);border-radius:11px;background:var(--surface);cursor:pointer;color:var(--text);}
.amc-iconbtn svg{width:22px;height:22px;}
.amc-appbar__center{flex:1;display:flex;justify-content:center;min-width:0;position:relative;}
.amc-locbtn{max-width:100%;min-width:0;display:flex;align-items:center;gap:8px;min-height:40px;padding:7px 15px;border:1px solid var(--chip-border);border-radius:999px;background:#F4F7F4;cursor:pointer;color:var(--text);}
.amc-locbtn__dot{width:8px;height:8px;border-radius:2px;background:var(--amc-black);flex:none;}
/* min-width:0 lets the nowrap name ellipsize instead of overflowing the centered control onto the
   hamburger + account buttons at narrow widths (which made those corner buttons unclickable). */
.amc-locbtn__name{font-size:15px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}
.amc-locbtn__chev{flex:none;display:flex;color:#7C858B;}
.amc-locbtn__chev svg{width:16px;height:16px;}
.amc-locstatic{display:flex;align-items:center;gap:8px;min-height:40px;padding:7px 14px;min-width:0;max-width:100%;}
.amc-account{width:44px;height:44px;flex:none;display:flex;align-items:center;justify-content:center;border:1px solid var(--chip-border);border-radius:999px;background:#F4F7F4;cursor:pointer;font-size:13px;font-weight:700;color:var(--text);letter-spacing:.02em;}

.amc-locmenu{position:absolute;top:calc(100% + 8px);left:50%;transform:translateX(-50%);z-index:30;width:min(320px,80vw);background:var(--surface);border:1px solid var(--chip-border);border-radius:13px;box-shadow:0 16px 40px -14px rgba(0,0,0,.4);padding:7px;display:flex;flex-direction:column;gap:5px;}
.amc-locmenu__title{font-size:11px;font-weight:700;color:#7C858B;text-transform:uppercase;letter-spacing:.04em;padding:5px 8px 3px;}
.amc-locopt{width:100%;display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:48px;padding:11px 13px;border-radius:11px;border:1.5px solid var(--border-strong);background:var(--surface);color:var(--text);font-size:15px;font-weight:600;cursor:pointer;text-align:left;text-decoration:none;}
.amc-locopt.is-active{border-color:var(--selected);background:var(--selected-surface);}

/* The shell canvas. The overflow:auto here dates from the first app-shell commit (39d9fff, Phase 2C) and
   predates the scroll-ownership law by months. On FRAMED screens it is correct and is re-declared
   deliberately below. On every OTHER screen it was silently wrong: an overflow container that never
   scrolls (it grows with its content while the WINDOW scrolls) still counts as the nearest scrolling
   ancestor, which disables position:sticky for every descendant. That is OFR-R5-I — it killed the
   work list's sticky day headers AND its sticky filter bar, app-wide, for the project's entire life.
   Scroll ownership is stated in docs/architecture/motion-and-continuity-laws.md; the non-framed rule
   below is the implementation of that law's "the window owns scrolling" clause, which until now the
   base rule contradicted. */
.amc-canvas{flex:1;min-height:0;overflow:auto;position:relative;}
.amc-app:not(.amc-app--framed) .amc-canvas{overflow:visible;}
.amc-page{padding:18px;max-width:940px;margin:0 auto;display:flex;flex-direction:column;gap:16px;}
.amc-page__title{margin:0;font-size:23px;font-weight:700;letter-spacing:-.01em;}
/* Mobile layout-viewport ownership (motion-and-continuity-laws.md). Subtitles carry machine metadata on
   the detail pages ("Safe display metadata: k=v · …"), which has no break opportunity. */
.amc-page__subtitle{margin:6px 0 0;font-size:14px;color:var(--text-muted);overflow-wrap:anywhere;}

/* operational home */
.amc-ops-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:13px;}
.amc-ops-card{text-align:left;background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:16px;display:flex;flex-direction:column;gap:9px;cursor:pointer;min-height:124px;text-decoration:none;color:var(--text);}
.amc-ops-card:hover{border-color:var(--border-strong);}
.amc-ops-card__top{display:flex;align-items:center;justify-content:space-between;gap:10px;}
.amc-ops-card__title{font-size:16px;font-weight:700;}
.amc-ops-card__arrow{color:#7C858B;display:flex;}
.amc-ops-card__arrow svg{width:18px;height:18px;}
.amc-ops-card__desc{font-size:13px;color:var(--text-muted);line-height:1.5;}
.amc-ops-card__tag{margin-top:auto;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:10px;letter-spacing:.05em;color:var(--text-faint);}
.amc-pending{text-align:left;display:flex;align-items:center;gap:12px;background:#EEF1EE;border:1px solid #CBD3C4;border-radius:12px;padding:14px 16px;cursor:pointer;text-decoration:none;color:var(--text);}
.amc-pending__count{min-width:28px;height:28px;border-radius:999px;background:var(--destructive);color:#fff;font-size:13px;font-weight:700;display:flex;align-items:center;justify-content:center;flex:none;}
.amc-pending__body{flex:1;font-size:14px;color:var(--positive);line-height:1.45;}
.amc-pending__cta{font-size:14px;font-weight:600;color:var(--text-muted);white-space:nowrap;}

/* tablist */
.amc-tabs{display:flex;flex-wrap:wrap;background:var(--chip-surface);border:1px solid var(--border);border-radius:11px;padding:3px;gap:3px;align-self:flex-start;}
.amc-tab{min-height:40px;padding:8px 16px;border-radius:8px;border:none;background:transparent;color:var(--text-muted);font-size:14px;font-weight:600;cursor:pointer;text-decoration:none;display:inline-flex;align-items:center;}
.amc-tab.is-active{background:var(--selected);color:var(--amc-black);}
.amc-tab__badge{margin-left:7px;min-width:18px;height:18px;padding:0 5px;border-radius:999px;background:var(--destructive);color:#fff;font-size:11px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;}

/* cards / lists */
.amc-list{display:flex;flex-direction:column;gap:11px;}
.amc-card{background:var(--surface);border:1px solid var(--border);border-radius:13px;padding:15px;display:flex;flex-direction:column;gap:12px;}
.amc-card__head{display:flex;flex-wrap:wrap;gap:10px;align-items:flex-start;justify-content:space-between;}
.amc-name{font-size:16px;font-weight:700;color:var(--text);}
.amc-rolechip{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11px;font-weight:600;color:var(--text);background:var(--chip-surface);border:1px solid var(--chip-border);border-radius:999px;padding:3px 9px;}
.amc-meta{font-size:12px;color:var(--text-muted);}
.amc-statuspill{display:inline-flex;align-items:center;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;border-radius:999px;padding:3px 8px;}
.amc-statuspill--active{background:var(--positive-surface);border:1px solid var(--positive-border);color:var(--positive);}
.amc-statuspill--disabled{background:#EFF2EF;border:1px solid #C8CFC8;color:var(--text-muted);}
.amc-statuspill--invited{background:#EEF1EE;border:1px solid #CBD3C4;color:var(--text-muted);}
.amc-nosession{margin-top:7px;font-size:12px;color:var(--text-muted);display:flex;align-items:center;gap:6px;}
.amc-nosession__dot{width:8px;height:8px;border-radius:999px;border:1.5px solid var(--amc-gray);}
.amc-actions{display:flex;flex-wrap:wrap;gap:9px;border-top:1px solid var(--divider);padding-top:12px;}
.amc-actions .amc-btn{flex:1 1 130px;min-height:44px;}
.amc-protected{border-top:1px solid var(--divider);padding-top:11px;font-size:12px;color:var(--amc-gray);display:flex;align-items:center;gap:7px;}
.amc-protected svg{width:15px;height:15px;}

.amc-empty{border:1.5px dashed var(--border-strong);border-radius:13px;padding:28px 20px;text-align:center;background:var(--surface-2);}
.amc-empty__title{font-size:16px;font-weight:600;color:var(--text);}
.amc-empty__body{margin-top:6px;font-size:14px;color:var(--text-muted);line-height:1.5;}
.amc-empty__action{display:flex;justify-content:center;margin-top:14px;}
.amc-empty__action .amc-btn{width:auto;}
.amc-empty--success{border-style:solid;border-color:var(--positive-border);background:var(--positive-surface);}
.amc-empty--success .amc-empty__title,.amc-empty__glyph{color:var(--positive);}
.amc-empty__glyph{margin-bottom:5px;font-size:20px;font-weight:800;line-height:1;}
.amc-section-label{font-size:13px;font-weight:600;color:#7C858B;letter-spacing:.02em;text-transform:uppercase;}

/* requests / expiring */
.amc-codebox{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:26px;font-weight:700;letter-spacing:.12em;color:var(--text);background:#EFF2EF;border:1px solid var(--chip-border);border-radius:9px;padding:6px 12px;}
.amc-warn{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;border-radius:999px;padding:3px 9px;}
.amc-warn--7{color:var(--destructive);background:var(--destructive-surface);border:1px solid var(--destructive-border);}
.amc-warn--21{color:var(--text-muted);background:var(--warning-surface);border:1px solid var(--border-strong);}

/* placeholder destination */
.amc-stub{border:1.5px dashed var(--border-strong);border-radius:14px;padding:42px 20px;text-align:center;background:var(--surface-2);font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12px;color:var(--text-faint);letter-spacing:.04em;}

/* rail collapse toggle (desktop) */
.amc-rail-toggle{display:none;}

/* desktop */
@media (min-width:880px){
  .amc-rail{display:flex;}
  .amc-appbar__menu{display:none;}
  .amc-rail-toggle{position:absolute;bottom:58px;width:44px;height:44px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;padding:0;cursor:pointer;z-index:6;border-radius:999px;left:192px;}
  .amc-rail-toggle__circle{width:28px;height:28px;border-radius:999px;background:var(--surface);border:1px solid var(--border-strong);box-shadow:0 2px 7px -1px rgba(0,0,0,.22);display:flex;align-items:center;justify-content:center;font-size:15px;font-weight:700;color:var(--text);line-height:1;}
  .amc-app.is-rail-collapsed .amc-rail{width:66px;}
  .amc-app.is-rail-collapsed .amc-rail__brand{flex-direction:column;align-items:center;gap:8px;padding:6px 0 12px;}
  .amc-app.is-rail-collapsed .amc-navbtn{justify-content:center;padding:8px 0;}
  .amc-app.is-rail-collapsed .amc-rail__label,
  .amc-app.is-rail-collapsed .amc-rail__brand-name,
  .amc-app.is-rail-collapsed .amc-navbtn__soon{display:none;}
  .amc-app.is-rail-collapsed .amc-navbtn__badge{position:absolute;top:3px;right:9px;margin:0;min-width:16px;height:16px;padding:0 4px;font-size:10px;}
  .amc-app.is-rail-collapsed .amc-rail-toggle{left:44px;}
}

/* ---------- overlays (drawer / sheets / modals) ---------- */
.amc-overlay{position:fixed;inset:0;background:rgba(20,20,18,.5);display:flex;align-items:center;justify-content:center;padding:18px;z-index:50;}
.amc-overlay[hidden]{display:none;}
.amc-overlay--scrim-soft{background:rgba(20,20,18,.16);}
.amc-overlay--bottom{align-items:stretch;justify-content:flex-end;flex-direction:column;padding:0;bottom:var(--amc-kb-inset,0px);}
.amc-overlay--centered{bottom:var(--amc-kb-inset,0px);}
.amc-overlay--centered>*,.amc-overlay--centered>.amc-overlay__wrap>*{max-height:92%;overflow:auto;}
.amc-overlay--left{justify-content:flex-start;align-items:stretch;padding:0;background:rgba(20,20,18,.42);}
.amc-modal{position:relative;background:var(--surface);border-radius:var(--radius-lg);padding:20px;width:100%;max-width:430px;max-height:92%;overflow:auto;}
.amc-modal__title{font-size:18px;font-weight:700;}
.amc-modal__body{margin-top:8px;font-size:14px;color:var(--text-muted);line-height:1.55;}
.amc-confirm{max-width:380px;}
.amc-confirm__title{margin:0;font-size:18px;font-weight:700;}
.amc-confirm__body{margin:8px 0 0;font-size:14px;color:var(--text-muted);line-height:1.55;}
.amc-confirm__actions{display:flex;gap:10px;margin-top:18px;}
.amc-confirm__actions .amc-btn{flex:1;min-height:46px;text-wrap:balance;}
.amc-confirm__actions--stacked{flex-direction:column;gap:4px;margin-top:6px;}
.amc-confirm__actions--stacked .amc-btn{flex:none;width:100%;min-height:45px;}
/* No CSS order property here, deliberately: ConfirmDialog emits the stacked children in visual order, so
   DOM/tab/AT order matches the paint. A CSS reorder silently reintroduces the WCAG 2.4.3/1.3.2 defect. */
.amc-confirm__actions--stacked .amc-confirm__cancel{background:none;border-color:transparent;color:var(--text-muted);}
.amc-modal__actions{display:flex;gap:10px;margin-top:18px;}
.amc-modal__actions .amc-btn{min-height:50px;font-size:15px;}
.amc-grip{width:38px;height:4px;border-radius:2px;background:var(--border-strong);margin:0 auto 14px;}
.amc-sheet{position:relative;background:var(--surface);border-radius:18px 18px 0 0;padding:18px 18px 24px;max-height:90%;overflow:auto;}
@media (max-width:879px){.amc-overlay--bottom .amc-sheet{box-sizing:border-box;width:100%;max-width:none;}}
.amc-drawer{position:relative;width:250px;max-width:84%;background:var(--surface);height:100%;display:flex;flex-direction:column;padding:16px 14px;gap:4px;box-shadow:0 0 40px rgba(0,0,0,.25);}
.amc-drawer__head{display:flex;align-items:center;justify-content:space-between;padding:4px 6px 14px;}
.amc-drawer__brand{display:flex;align-items:center;gap:9px;background:none;border:none;padding:0;cursor:pointer;}
.amc-drawer__brand img{width:28px;height:28px;border-radius:7px;}
.amc-menubtn{position:relative;display:flex;align-items:center;gap:12px;width:100%;text-align:left;min-height:50px;padding:11px 13px;border-radius:11px;border:none;background:transparent;color:var(--text);font-size:15px;font-weight:600;cursor:pointer;text-decoration:none;}
.amc-menubtn.is-active{background:var(--selected);color:var(--amc-black);}
.amc-overlay__rest{position:absolute;inset:0;}
/* DESIGN-001 Phase B — React Aria overlay glue. The AriaModal wrap is a passthrough so .amc-modal /
   .amc-sheet center within .amc-overlay exactly as the hand-rolled sheets did; the popover wrapper carries
   z-index above page content; the popover trigger is a bare button (its look comes from the trigger content). */
.amc-overlay__wrap{display:contents;}
.amc-pop{z-index:56;}
.amc-pop__trigger{background:none;border:none;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;display:inline-flex;}

/* DF-019 — before/after route-position picker (the searchable, weekday-grouped complement to drag). */
.amc-posn__title{font-size:18px;font-weight:700;margin:0 0 2px;}
.amc-posn__subtitle{font-size:13px;margin:0 0 14px;line-height:1.45;}
.amc-posn__preview{margin:14px 0 4px;font-size:13px;line-height:1.5;background:var(--surface-2);border:1px solid var(--border);border-radius:10px;padding:9px 12px;}
.amc-posn__cross{display:block;margin-top:4px;font-size:12px;}
.amc-posn__scope-note{margin:8px 0 0;font-size:12px;line-height:1.5;}
.amc-posn__openroute{display:inline-block;margin:12px 0 0;font-size:13px;}
.amc-posn__actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:16px;}
.amc-posn__actions .amc-btn{flex:1;min-height:48px;}
@media (max-width:360px){.amc-posn__actions{grid-template-columns:1fr;}}
@media (min-width:880px){.amc-overlay--bottom .amc-posn{border-radius:var(--radius-lg);margin-bottom:14vh;}}
.amc-route__movebtn{margin-left:10px;width:auto;min-height:0;padding:0;font-size:12.5px;}
/* Round 2 (item g) — the per-row "Open ↗" link into the location drill-down. */
.amc-route__openlink{margin-left:10px;width:auto;min-height:0;padding:0;font-size:12.5px;white-space:nowrap;}
/* React Aria ComboBox (used by the position picker; reusable across reschedule surfaces). */
.amc-combo{display:block;margin:0 0 12px;}
.amc-combo__label{display:block;font-size:12px;font-weight:700;color:var(--text-muted);margin:0 0 4px;}
.amc-combo__field{position:relative;display:flex;align-items:center;}
.amc-combo__input{width:100%;padding-right:50px;}
.amc-combo__btn{position:absolute;right:3px;top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border:none;background:none;color:var(--text-muted);font-size:15px;cursor:pointer;border-radius:8px;}
.amc-combo__btn:hover{background:var(--surface-2);color:var(--text);}
/* RUNAWAY GUARD (SL-OVERFLOW-001). width:var(--trigger-width) makes this popover copy its anchor, so on a
   page that already overflows horizontally it joins a POSITIVE FEEDBACK LOOP: overflow -> Chromium
   shrink-to-fit reports a wider layout viewport -> the viewport-relative page and its anchor grow -> the
   popover copies the wider anchor -> its right edge pushes the document wider again. Measured on the
   deployed mobile lane before the Route Order containment fix: innerWidth 476 -> 543 -> 1560 over 101
   frames, the popover's right edge tracking to 1571 at a 390px device. vw resolves against the initial
   containing block, which the minimum-scale adjustment does NOT widen (100vw stayed 390 while innerWidth
   read 476), so this is a fixed ceiling the loop cannot inflate. Guard, not a layout change: 390 allows
   358.8px and every mount renders 354px (18px gutters) — before/after verified on all seven. min-width
   still wins below ~261px, and that floor is a constant. */
/* overscroll-behavior: OFR-R7-S6-OVERLAY-OVERSCROLL (law in RoutePositionEditor.tsx) — chaining out of this
   port scrolled the WINDOW, and React Aria closes a non-modal popover on any ancestor scroll. */
.amc-combo__pop{z-index:60;background:var(--surface);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow-pop);max-height:300px;overflow:auto;overscroll-behavior:contain;min-width:240px;width:var(--trigger-width);max-width:92vw;}
.amc-combo__list{padding:4px;outline:none;}
.amc-combo__sechdr{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--text-faint);padding:8px 8px 3px;}
.amc-combo__opt{display:flex;flex-direction:column;justify-content:center;gap:1px;min-height:44px;padding:7px 9px;border-radius:7px;cursor:pointer;outline:none;}
.amc-combo__opt[data-focused]{background:var(--surface-2);}
.amc-combo__opt[data-selected]{background:var(--selected-soft);}
.amc-combo__opt--sentinel{font-weight:600;color:var(--text);}
.amc-combo__optlabel{font-size:14px;color:var(--text);}
.amc-combo__optsub{font-size:12px;color:var(--text-muted);}
.amc-posnrow{display:flex;align-items:baseline;gap:6px;min-width:0;width:100%;}
.amc-posnrow__glyph{flex:none;font-size:12px;color:var(--text-muted);}
/* WORKFIT-001 sibling — the route-position picker's stop row carries the same identity fields as a work-list
   Sort row, so it takes the same content-sized law and yield order. Its badge was capped at 28% of the row
   with NO relief tier at any width: a percentage of the row is a constant too, blind to what the row holds. */
.amc-posnrow .amc-combo__optlabel{font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:0 400 auto;min-width:3ch;}
.amc-posnrow .amc-labelbadge{flex:0 20 auto;min-width:3ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.amc-posnrow__addr{min-width:5ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;color:var(--text-muted);}

/* account panel */
.amc-account-panel{position:relative;background:var(--surface);border-radius:18px 18px 0 0;padding:18px 18px 24px;max-height:88%;overflow:auto;}
.amc-account-id{display:flex;align-items:center;gap:12px;}
.amc-account-id__avatar{width:46px;height:46px;border-radius:999px;background:var(--amc-black);color:#fff;display:flex;align-items:center;justify-content:center;font-size:15px;font-weight:700;flex:none;}
.amc-account-id__name{font-size:17px;font-weight:700;letter-spacing:-.01em;}
.amc-account-loc{margin-top:15px;padding-top:13px;border-top:1px solid var(--divider);}
.amc-account-loc__label{font-size:12px;font-weight:600;color:#7C858B;text-transform:uppercase;letter-spacing:.03em;margin-bottom:6px;}
.amc-account-loc__body{font-size:14px;color:var(--text);line-height:1.5;}
.amc-account-actions{margin-top:16px;display:flex;flex-direction:column;gap:9px;}
.amc-account-actions .amc-btn{min-height:48px;font-size:15px;}
@media (min-width:880px){
  .amc-account-panel{position:absolute;top:62px;right:14px;width:308px;border:1px solid var(--chip-border);border-radius:14px;padding:16px;box-shadow:var(--shadow-pop);max-height:80%;border-radius:14px;}
  .amc-account-panel .amc-grip{display:none;}
}

/* selectable chips / role rows in modals */
.amc-chip{min-height:44px;padding:0 15px;border-radius:999px;font-size:14px;font-weight:600;cursor:pointer;border:1.5px solid var(--border-strong);background:var(--surface);color:var(--text);}
.amc-chip.is-selected{border-color:var(--amc-black);background:var(--amc-black);color:#fff;}
.amc-chiprow{display:flex;flex-wrap:wrap;gap:8px;}
.amc-roleopt{width:100%;display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:54px;padding:11px 14px;border-radius:11px;border:1.5px solid var(--border-strong);background:var(--surface);color:var(--text);cursor:pointer;text-align:left;}
.amc-roleopt.is-selected{border-color:var(--amc-black);background:#EFF2EF;}
.amc-roleopt__label{font-size:15px;font-weight:600;}
.amc-roleopt__code{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11px;color:var(--amc-gray);}

/* attestation check */
.amc-attest{margin-top:15px;width:100%;display:flex;align-items:flex-start;gap:11px;text-align:left;background:var(--surface-2);border:1px solid var(--chip-border);border-radius:12px;padding:14px;cursor:pointer;}
.amc-attest__box{width:24px;height:24px;flex:none;border-radius:6px;border:2px solid var(--amc-gray);background:#fff;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px;}
.amc-attest.is-checked .amc-attest__box{border-color:var(--positive);background:var(--positive);}
.amc-attest__text{font-size:14px;color:var(--text);line-height:1.5;font-weight:600;}

/* one-time code reveal */
.amc-codeblock{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:13px;line-height:1.6;word-break:break-all;background:#EFF2EF;border:1px solid var(--chip-border);border-radius:10px;padding:13px 14px;color:var(--text);}

/* Notification law: success may auto-dismiss; refusals/errors remain until Close. All message text is
   selectable so an owner can copy exact evidence into an interaction-check report. */
.amc-toast{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);background:var(--amc-black);color:#fff;font-size:14px;font-weight:500;padding:12px 14px 12px 18px;border-radius:11px;box-shadow:0 12px 30px -10px rgba(0,0,0,.5);animation:amc-toast .2s ease;min-width:min(300px,calc(100vw - 32px));max-width:min(760px,calc(100vw - 32px));text-align:left;z-index:60;display:inline-flex;align-items:center;gap:14px;user-select:text;-webkit-user-select:text;}
.amc-toast[hidden]{display:none;}
.amc-toast--error,.amc-toast--refusal{box-shadow:inset 4px 0 0 var(--destructive),0 12px 30px -10px rgba(0,0,0,.5);}
.amc-toast__message{min-width:0;white-space:pre-wrap;overflow-wrap:anywhere;user-select:text;-webkit-user-select:text;}
.amc-toast__close{appearance:none;flex:none;min-width:44px;min-height:44px;border:1px solid rgba(255,255,255,.48);border-radius:8px;background:transparent;color:#fff;font:inherit;font-weight:700;line-height:1;padding:8px 10px;cursor:pointer;white-space:nowrap;user-select:none;-webkit-user-select:none;}
.amc-toast__close:hover{background:rgba(255,255,255,.12);}
/* run-F1 "no dead ends": an optional inline toast action (e.g. Undo a dismissal) — Citrus so it reads on the
   dark toast, overriding the default link-button colour. */
.amc-toast__action.amc-btn--link{flex:none;width:auto;min-width:44px;min-height:44px;color:var(--selected);font-weight:700;text-decoration:underline;padding:0;white-space:nowrap;}

/* ===== Jobs registry + Create Job (Phase 3B) ===== */
.amc-page__head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:14px;}
/* Owner finding #10 (IC-r9, 2026-09-04) — Jobs Configuration and Service Locations/Route Order are both
   framed, height-budgeted screens (SORT-004): every px this head spends is a px the row grid loses. The
   compact variant shrinks the title/subtitle and the head's own margin; it changes nothing about
   amc-page__head everywhere else. */
.amc-page__head--compact{margin-bottom:8px;}
.amc-page__head--compact .amc-page__title{font-size:18px;}
.amc-page__head--compact .amc-page__subtitle{margin-top:3px;font-size:12.5px;}
.amc-cfg-stopday-cell{display:inline-flex;align-items:center;gap:4px;}
.amc-cfg-stopday{white-space:nowrap;}
.amc-page--narrow{max-width:680px;}
.amc-muted{color:var(--text-faint);}
.amc-link{color:var(--positive);font-weight:600;text-decoration:none;}
.amc-link:hover{text-decoration:underline;}

/* registry table */
.amc-tablewrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);}
.amc-jobs-table{width:100%;border-collapse:collapse;font-size:13px;color:var(--text);min-width:880px;}
.amc-jobs-table th{text-align:left;font-weight:700;font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--text-muted);padding:10px 12px;border-bottom:1.5px solid var(--border);background:var(--surface-2);white-space:nowrap;}
.amc-jobs-table td{padding:10px 12px;border-bottom:1px solid var(--divider);vertical-align:top;}
.amc-jobs-table tr:last-child td{border-bottom:none;}
.amc-labelbadge{display:inline-block;font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--text);background:var(--selected-surface);border:1px solid var(--positive-border);border-radius:6px;padding:1px 6px;margin-right:2px;}

/* weekly work list (Phase 4) */
.amc-weeknav{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:6px;}
.amc-visitday{margin-top:14px;}
.amc-visitday__head{margin:0 0 8px;padding:6px 10px;border:1px solid var(--border-strong);border-radius:var(--radius-sm);background:var(--divider-band-surface);font-size:14px;font-weight:700;color:var(--divider-band-foreground);}
.amc-mcpage[data-sort-mode="off"] .amc-visitday__head{position:sticky;top:var(--amc-day-sticky-top,0px);z-index:10;box-shadow:0 2px 5px rgba(45,41,38,.12);}
/* IC-R7 finding T (owner ruling) — TODAY = filled weekday pill + a ring on the day list, REPLACING the OFR-R5 rail/wash that washed a band in the RESERVED complete colour. display:inline is load-bearing (inline vertical padding paints without growing the line box, so header height and the divider grip cannot move); the ring carries today through Sort, where headers are drag surfaces and not sticky.
   Rationale, the overwritten TODAY-SORT-ACCENT clause and why .amc-visitday__label exists: docs/history/ic-r7-finding-t-remediation.md. */
.amc-visitday__head[data-today="yes"] .amc-visitday__weekday{display:inline;background:#2563A8;color:#fff;font-weight:700;border-radius:999px;padding:2px 11px;}
.amc-visitday__head[data-today="yes"] + .amc-joblist{box-shadow:inset 0 0 0 2px #2563A8;}
.amc-visitday__head--missed{border-left:4px solid var(--flag-carry);background:color-mix(in srgb,var(--flag-carry) 7%,var(--divider-band-surface));}
/* The day header AS the draggable boundary divider (Phase 10.7): a grip sits on the header, no separate strip. */
.amc-visitday__head--divider{display:flex;align-items:center;gap:8px;cursor:grab;}
/* SORT-003: the work-list surface gives this divider grip the shared 28px-wide exclusive target. */
.amc-visitday__head--divider.amc-dragrow--placeholder{opacity:.45;}

/* lifecycle chips (extend the shared .amc-chip) */
.amc-chip--life-active{background:var(--positive-surface);border-color:var(--positive-border);color:var(--positive);}
/* Round 2 (2A): "Done" (a past one-time job) — a calm "finished" slate, distinct from Paused (amber) and
   the reserved status colours (green=complete, red/fuchsia=QC, orange=carry-forward, citrus=selected). */
.amc-chip--life-done{background:color-mix(in srgb, var(--text-muted) 13%, var(--surface));border-color:var(--border-strong);color:var(--text);}
.amc-chip--life-paused{background:var(--warning-surface);border-color:var(--border-strong);color:var(--text-muted);}
.amc-chip--life-under_review{background:var(--surface-2);border-color:var(--border-strong);color:var(--text-muted);}
.amc-chip--life-archived{background:var(--surface-2);border-color:var(--border);color:var(--text-faint);}

/* highlight swatch (non-semantic palette token) */
.amc-hl{display:inline-block;width:14px;height:14px;border-radius:4px;border:1px solid var(--border-strong);vertical-align:middle;}
.amc-hl--none{background:repeating-linear-gradient(45deg,var(--surface-2),var(--surface-2) 3px,var(--divider) 3px,var(--divider) 6px);}
.amc-hl--yellow{background:var(--hl-yellow);}
.amc-hl--pink{background:var(--hl-pink);}
.amc-hl--blue{background:var(--hl-blue);}
.amc-hl--purple{background:var(--hl-purple);}
.amc-hl--cyan{background:var(--hl-cyan);}

/* create job form */
.amc-jobform{display:flex;flex-direction:column;gap:14px;}
.amc-jobfield{display:flex;flex-direction:column;gap:6px;}
.amc-jobfield__label{font-size:13px;font-weight:600;color:var(--text);}
/* POLISH-JOBFORM-001 — paired fields own a form-specific class. Reusing the work-list row class here
   previously let unrelated work-list rail declarations override this layout and, before OFR-R5-B's
   interim scope repair, leaked this 12px gap into every field-operations row. A real grid restores the
   intended desktop pairing; minmax(0,1fr) keeps either field's intrinsic width from widening its track. */
.amc-jobform__row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;}
.amc-jobtext{min-height:74px;resize:vertical;font-family:inherit;line-height:1.5;}
.amc-sched{border:1px solid var(--border);border-radius:var(--radius);padding:12px 14px;display:flex;flex-direction:column;gap:12px;margin:0;}
.amc-sched legend{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);padding:0 4px;}
.amc-preview{font-size:13px;line-height:1.6;color:var(--text);background:var(--surface-2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:10px 12px;}
.amc-preview[hidden]{display:none;}
.amc-hlrow{display:flex;flex-wrap:wrap;gap:8px;}
.amc-hlopt{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--text);background:var(--surface);border:1.5px solid var(--field-border);border-radius:9px;padding:6px 10px;cursor:pointer;min-height:36px;}
.amc-hlopt.is-selected{border-color:var(--focus);background:var(--selected-surface);font-weight:600;}
.amc-hlopt__label{text-transform:capitalize;}
.amc-jobactions{display:flex;justify-content:flex-end;gap:10px;margin-top:4px;}
@media (max-width:560px){.amc-jobform__row{grid-template-columns:minmax(0,1fr);}}

/* jobs import (CSV upload / paste-from-Sheets, preview + partial commit) */
.amc-import{display:flex;flex-direction:column;gap:16px;}
.amc-import__textarea{width:100%;min-height:200px;padding:12px 14px;border:1.5px solid var(--field-border);border-radius:10px;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:13px;line-height:1.5;color:var(--text);background:var(--surface);outline:none;resize:vertical;}
.amc-import__file{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
.amc-import__hint{font-size:12px;color:var(--text-muted);line-height:1.5;}
.amc-import__summary{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;font-size:15px;font-weight:700;color:var(--text);}
.amc-import__cols{font-size:12px;color:var(--text-muted);line-height:1.7;}
.amc-import__actions{display:flex;justify-content:flex-end;gap:10px;flex-wrap:wrap;}
.amc-import-row--error{background:color-mix(in srgb, var(--flag-rework) 8%, var(--surface));}
.amc-import-status{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:700;white-space:nowrap;}
.amc-import-status--ok{color:var(--positive);}
.amc-import-status--error{color:var(--flag-rework);}
.amc-import-errs{margin:0;padding-left:16px;color:var(--flag-rework);font-size:12px;line-height:1.5;}
.amc-import-errs li{margin:1px 0;}

/* ===== Mark Complete / unified work list (Phase 5.1 — React field workflow) ===== */
/* Reuses the semantic tokens. Reserved colours respected: Evergreen/green = complete,
   Citrus = selected/marked; the accidental-correction "undo" control is intentionally NEUTRAL
   (never Fuchsia/red — that is reserved for QC failure, a separate Phase 6 path).
   Dense, spreadsheet-like rows (owner round 2): instructions are the primary content; recurrence is
   a tiny glyph; schedule metadata lives behind an expand. */
.amc-mcpage{max-width:820px;padding-bottom:128px;}
.amc-mcpage__head{margin-bottom:6px;}
.amc-spin--dark{border:2px solid var(--selected-soft);border-top-color:var(--text);width:15px;height:15px;}
.amc-inline-link{display:inline;width:auto;min-height:0;padding:0 0 0 2px;}

/* filter bar — collapsed to one compact, sticky line; expands to presets + controls */
/* N6: the loading cover may block list gestures, but a date commit cannot bury the filter controls. */
/* OFR-R5-K — a sticky element TALLER than the viewport traps its own overflow: it pins at top:0 and the
   part below the fold can never be scrolled to. The expandable filter panel (.amc-disclose) lives inside
   this bar, so an expanded panel on a short viewport (landscape phone, small window) put its lower
   controls permanently out of reach. Latent since the bar was written; only reachable once OFR-R5-I made
   sticky actually work, so this shipped as a same-day regression of that fix. The cap plus internal
   scrolling makes the panel reachable at ANY viewport height, and leaves a strip of the list visible so
   the bar never reads as a full-screen takeover. Standing rule: any sticky element whose height is
   content-driven needs a max-height and its own scroll, or it becomes a trap.
   R5-V-FAB-PADDING (refuted r1) — while the panel is EXPANDED that cap must also be a VIEWPORT-coordinate
   reservation. 86dvh is measured from the bar's own top edge, and at rest that edge sits ~166px down the
   page, so the bar's bottom lands 47-111px BELOW the fold: the panel's terminal scroll parks its last action
   underneath the bottom-fixed controls, and no content-box padding inside the panel can fix it (the
   sufficient constant measured 80-214px across viewport/lens because it has to absorb barTop, which the
   panel cannot see). The expanded bar stops at 100dvh MINUS the measured barTop MINUS the fixed-control
   band: FilterPanel's ResizeObserver publishes --amc-filterbar-top and --amc-fab-reserve is derived beside
   the FAB rules that set the band. 86dvh is KEPT as the R5-K takeover guard — min() takes whichever bound is
   tighter. The bound is scoped to [data-open="yes"] on purpose: it can legitimately resolve smaller than the
   collapsed head (a landscape phone with a raised band leaves 12px), and clamping a COLLAPSED bar to a
   sliver would trade this bug for a worse one. Collapsed geometry is therefore byte-identical to before. */
.amc-filterbar{position:sticky;top:0;z-index:15;background:var(--bg);padding:4px 0 6px;margin-bottom:8px;max-height:86dvh;overflow-y:auto;overscroll-behavior:contain;}
.amc-filterbar[data-open="yes"]{max-height:min(86dvh,calc(100dvh - var(--amc-filterbar-top,0px) - var(--amc-fab-reserve,0px)));}
/* R5-V-FILTER-LABEL (refuted r1) — the collapsed toggle must ALWAYS show both its purpose label and its
   matched/total count. While the head was a single non-wrapping row, flex:1 + min-width:0 let the sibling
   pills (My work / Dismissed) squeeze the toggle to 26px: the count left the control and the pills then
   PAINTED OVER the label — an occlusion a clip-only oracle cannot see. The head now wraps and the toggle
   carries a floor wide enough for its fixed parts, so the pills drop to a second line before the toggle is
   crushed. Floor derivation: 24 padding + 2 borders + 12 chevron + 24 (three 8px gaps) + 45 "FILTER:" +
   ~87 widest count = 194 -> 200. (Measured in Archivo: the label is 45px and a "12 of 40" count chip is
   68.4px; 87 budgets a three-digit "100 of 100" plus the chip's own padding and border.) The optional
   "Missed first" hoist chip adds a 5th child and one more 8px gap; it is the ONLY child allowed to yield
   (see .amc-hoistmode), so the count never does.
   The bar's ResizeObserver publishes --amc-day-sticky-top from the MEASURED bar height, so a wrapped and
   therefore taller bar re-pins the day headers instead of overlapping them — no sticky offset is hardcoded. */
.amc-filterbar__head{display:flex;flex-wrap:wrap;align-items:center;gap:8px;}
.amc-filterbar__toggle{flex:1 1 200px;min-width:200px;display:flex;align-items:center;gap:8px;min-height:42px;padding:7px 12px;border:1px solid var(--chip-border);border-radius:999px;background:var(--surface);color:var(--text);cursor:pointer;text-align:left;}
.amc-filterbar__chev{flex:none;color:var(--text-muted);font-size:11px;width:12px;}
.amc-filterbar__label{flex:none;color:var(--text-muted);font-size:11px;font-weight:700;letter-spacing:.04em;white-space:nowrap;}
.amc-filterbar__summary{flex:1;min-width:0;font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.amc-filterbar__count{flex:none;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11px;color:var(--text-muted);background:var(--chip-surface);border:1px solid var(--chip-border);border-radius:999px;padding:2px 9px;}
.amc-filterbar__share{flex:none;}
/* R5-V-DISMISSED-ICON — the manager's uncommon history lens yields its visible word on phones while
   preserving that sole accessible-name source with the shared .amc-sr 1px/clip contract. Above the
   phone tier the span has ordinary inline geometry, so the explanatory word returns automatically. */
@media (max-width:720px){.amc-filterbar__dismissed-label{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}}
@media (max-width:720px){.amc-filterbar__mine-label{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}}
/* R5-V-FAB-PADDING — the panel keeps its ordinary 13px padding on purpose: the landing zone above the
   bottom-fixed controls is owned by the SCROLLER's viewport bound (.amc-filterbar above), not by content-box
   padding in here. See --amc-fab-reserve beside the FAB rules for the band derivation. */
.amc-filterpanel{margin-top:8px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:13px;display:flex;flex-direction:column;gap:13px;}
.amc-filterrow{display:flex;flex-direction:column;gap:7px;}
.amc-filterrow__label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);}
.amc-filterrow__select,.amc-filterrow__search{max-width:340px;min-height:42px;}
.amc-filterrow__weeklabel{align-self:center;}
.amc-filterpanel__foot{display:flex;align-items:center;justify-content:space-between;gap:10px;border-top:1px solid var(--divider);padding-top:11px;}
.amc-chip--hl{text-transform:capitalize;}
.amc-chip--hl .amc-hl{vertical-align:-2px;}

/* dense job rows — modeled on the Forms checkbox list */
.amc-joblist{display:flex;flex-direction:column;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);overflow:hidden;}
/* Round 2 (item 1): during a cross-day drag, drop the overflow clip so the lifted row stays visible as it
   travels between day lists (the z-raised .amc-dragrow--lifted paints above later days). */
.amc-joblist[data-dragging="yes"],.amc-joblist.amc-joblist--flip-open{overflow:visible;}
/* OFR-R5-C (owner ruling 2026-08-03, "alpha seam") — rows are separated by a TRANSPARENCY seam, not a
   fixed-colour hairline. The old 1px solid var(--divider) was chosen against a white row and measured
   1.00:1 against the blue tint, 1.03:1 against purple/pink/cyan and 1.08:1 against yellow (WCAG floor
   for a non-text boundary is 3:1) — i.e. mathematically invisible on every highlight. Because both
   edges here are alpha, they composite over WHATEVER is behind them, so all five tints, checked rows,
   completed rows, flag states, any future colour and any future dark theme separate correctly with no
   per-case tuning.
   LAW N8 (interaction-feedback-laws.md), OFR-R5-RAILS-SEAM: box-shadow does NOT accumulate across
   rules — it is last-wins ACROSS every semantic axis at once, so five separate state rules silently
   deleted or overpainted one another's rails. The original claim that three also deleted this seam was
   false: all 98 base combinations rendered both seam layers. The fix is not a convention ("remember to
   re-include it"); the future hazard is removed. .amc-jobrow carries EXACTLY ONE
   box-shadow declaration — this one — composed of three SLOT custom properties plus the seam. State
   rules set a slot and never box-shadow. A slot is last-wins WITHIN its own axis, which is correct.
   Layer order is narrow-slot-first because box-shadow paints the FIRST layer on TOP: --rail-flag is
   the 6px OUTER slot, so it must sit UNDER the 3px inner slots or it would cover them entirely. */
.amc-jobrow{--seam:inset 0 1px 0 rgba(255,255,255,.62), inset 0 -1px 0 rgba(45,41,38,.15);
  --rail-select:inset 0 0 0 transparent; --rail-future:inset 0 0 0 transparent; --rail-flag:inset 0 0 0 transparent;
  display:flex;flex-direction:column;box-shadow:var(--rail-select), var(--rail-future), var(--rail-flag), var(--seam);}
.amc-jobrow.is-checked{background:var(--selected-surface);--rail-select:inset 3px 0 0 var(--selected);}
.amc-jobrow--done{background:var(--positive-surface);}
/* DF-008 — a completed visit that was later QC-failed is superseded: a muted gray/light-red tint (overrides
   the green done surface) + a slightly dimmed row, so the eye reads "done but redone" while the live red
   rework row carries the active work. Defined AFTER --done so it wins the background. */
.amc-jobrow--qcfailed{background:color-mix(in srgb, var(--flag-rework) 8%, var(--surface-2));}
.amc-jobrow--qcfailed .amc-jobrow__name{color:var(--text-muted);}
.amc-jobrow__status--qcfailed{color:var(--flag-rework);font-weight:700;}
/* DF-011 — one imperative phone-gesture boundary paints this track without re-rendering the row. Parent
   open-id ownership supplies the resting transform; a horizontal sequence temporarily disables the shared,
   brisk settle transition. 104px = PHONE_SWIPE_CONFIG.revealPx. */
.amc-jobrow__swipe{overflow:hidden;}
.amc-jobrow__swipetrack{display:flex;width:calc(100% + 104px);touch-action:pan-y;transition:transform var(--motion-settle) var(--ease-out);}
.amc-jobrow__swipetrack[data-swipe-dragging="yes"]{transition:none;}
/* OFR-R5-B — 48→44px. This is the SECOND independent 48px floor on the row's flex line; lowering the
   one on .amc-jobrow__main alone produces literally zero change because this one still holds the line. */
.amc-swipeaction{flex:0 0 104px;display:flex;align-items:center;justify-content:center;gap:5px;border:none;color:#fff;font-size:13px;font-weight:700;cursor:pointer;min-height:44px;transition:background-color var(--motion-press) var(--ease),box-shadow var(--motion-press) var(--ease),color var(--motion-press) var(--ease);}
.amc-swipeaction--complete{--swipe-paint:var(--positive);background:var(--swipe-paint);box-shadow:-50vw 0 0 50vw var(--swipe-paint);}
.amc-swipeaction__label--commit{display:none;}
.amc-jobrow__swipetrack[data-swipe-commit="yes"] .amc-swipeaction__label--reveal{display:none;}
.amc-jobrow__swipetrack[data-swipe-commit="yes"] .amc-swipeaction__label--commit{display:inline;}
/* D6 — deliberate brand-hue reuse: Citrus and --selected currently share #92D500, but this is a commit
   signal, never selection state. Dark brand ink preserves readable contrast while both colours interpolate. */
.amc-jobrow__swipetrack[data-swipe-commit="yes"] .amc-swipeaction--complete{--swipe-paint:var(--amc-citrus);color:var(--amc-black);}
.amc-swipeaction:disabled{pointer-events:none;}
.amc-jobrow__swipe .amc-jobrow__main{flex:1 1 auto;min-width:0;}
/* Carry-forward stack (cluster 2): a subsidiary carry-forward row sits INDENTED under its job-week stack's
   primary (mow) row, with a faint left guide so the stack reads as one group (checking any member checks
   them all). Works for both the open (column) and done (row) layouts. */
.amc-jobrow--stacked{padding-left:18px;position:relative;}
.amc-jobrow--stacked::before{content:"";position:absolute;left:8px;top:0;bottom:0;width:2px;background:var(--divider);border-radius:2px;}
/* OFR-R5-B — padding-top 8→4 and min-height 48→44. This element carries role="checkbox" and IS the
   primary phone completion target, so 44px is a hard floor (tests/ui/a11y.spec.ts asserts it); the
   measured row lands at 46px, above the floor. Untouched by any density round since 2026-06-17. */
.amc-jobrow__main{display:flex;align-items:flex-start;gap:10px;min-height:44px;padding:4px 11px 2px;cursor:pointer;touch-action:pan-y;user-select:none;-webkit-user-select:none;}
.amc-jobrow__main:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
.amc-jobrow__box{flex:none;width:24px;height:24px;margin-top:1px;border-radius:6px;border:2px solid var(--field-border);background:var(--surface);display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px;font-weight:700;}
/* DF-015b — the checkbox + recurrence glyph stack in a column (glyph a small muted indicator UNDER the box). */
.amc-jobrow__checkcol{flex:none;display:flex;flex-direction:column;align-items:center;gap:3px;}
.amc-jobrow__glyph--under{font-size:12px;line-height:1;color:var(--text-muted);}
.amc-jobrow.is-checked .amc-jobrow__box{border-color:var(--positive);background:var(--positive);}
/* The completed row's box aligns with the done layout but renders UNCHECKED (neutral border, no green
   fill, no checkmark) so it never reads as a still-checked draft selection; done-ness is conveyed by
   the green row + "✓ Done" status (owner round-2 fix). */
.amc-jobrow__box--done{flex:none;width:24px;height:24px;margin:9px 0 0 11px;border-radius:6px;}
/* DF-010 — the completed-row checkbox slot becomes the manager 🚨 QC-fail button (truer-red border + tint). */
.amc-jobrow__box--qcfail{border:1.5px solid var(--flag-rework);background:color-mix(in srgb, var(--flag-rework) 10%, var(--surface));cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:12px;padding:0;line-height:1;}
.amc-jobrow__box--qcfail:hover{background:color-mix(in srgb, var(--flag-rework) 20%, var(--surface));}
.amc-jobrow__box--qcfail:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.amc-jobrow--done{flex-direction:row;align-items:flex-start;}
.amc-jobrow--done .amc-jobrow__text{padding:8px 11px 2px 0;}
.amc-jobrow__text{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;}
.amc-jobrow__line1{display:flex;align-items:baseline;flex-wrap:wrap;gap:3px 8px;min-width:0;}
.amc-jobrow__id{display:inline-flex;align-items:baseline;flex-wrap:wrap;gap:3px 7px;min-width:0;}
.amc-jobrow__id .amc-hl{align-self:center;}
.amc-jobrow__name{font-size:14px;font-weight:700;color:var(--text);}
/* HIERARCHY-004 — the location setting changes entry affordances only. Scope the persistent touch-visible
   cue to enabled work-list anchors so OFF retains the pre-feature row styling and dismissed customer names
   do not inherit the generic .amc-link colour/weight. */
a[data-work-list-label-link]{text-decoration-line:underline;text-decoration-thickness:1px;text-underline-offset:.16em;}
.amc-jobrow__glyph{font-size:12px;color:var(--text-muted);}
/* Round 2 (item d) — the address + zone chip ride together as ONE inline unit (.amc-jobrow__addrline) so the
   zone is ALWAYS beside the address and never wraps onto its own row. Collapsed: the address ellipsizes (…);
   expanded (row data-expanded="yes"): the address wraps; the zone chip is flex:none and stays put either way. */
.amc-jobrow__addrline{display:inline-flex;align-items:baseline;gap:0 6px;min-width:0;max-width:100%;}
.amc-jobrow__addr{font-size:12.5px;color:var(--text-muted);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.amc-jobrow[data-expanded="yes"] .amc-jobrow__addr{white-space:normal;overflow:visible;}
.amc-jobrow__zonechip{flex:none;font-size:11px;font-weight:600;color:var(--text-muted);background:var(--surface-2);border:1px solid var(--border);border-radius:999px;padding:1px 8px;white-space:nowrap;}
/* ASSIGN-UNASSIGN-001 - the work-list row's mark for a DELIBERATELY unassigned visit. Only the
   explicit state is marked; an ordinary unassigned row keeps its silent appearance. */
.amc-jobrow__nobodychip{flex:none;font-size:11px;font-weight:700;color:var(--text-muted);background:var(--surface-2);border:1px dashed var(--border);border-radius:999px;padding:1px 8px;white-space:nowrap;}
/* Sort mode forces the compact layout (item b); keep the routing zone chip out of it to stay dense. */
.amc-jobrow--compact .amc-jobrow__zonechip{display:none;}
.amc-jobrow__status{margin-left:auto;font-size:11px;font-weight:700;color:var(--text-faint);white-space:nowrap;}
.amc-jobrow__status--marked,.amc-jobrow__status--done{color:var(--positive);}
/* DF-015c — the zone in the line-1 status slot reads as a quiet routing tag (a chip, not a status word). */
.amc-jobrow__status--zone{font-weight:600;color:var(--text-muted);background:var(--surface-2);border:1px solid var(--border);border-radius:999px;padding:1px 8px;}
/* The bold completion date above a done row's instructions (normal completion surface only). */
.amc-jobrow__donedate{font-weight:700;font-size:12px;color:var(--positive);margin:0 0 2px;}
/* Assignment chips (display-only). Neutral slate tone — deliberately avoids the reserved semantic colours
   (green=done, red/fuchsia=QC, orange=carry-forward, citrus=selected). A row assigned to the viewer gets a
   subtly stronger border via .is-mine. */
.amc-jobrow__assignees{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin:2px 0 0;}
.amc-assignchip{display:inline-flex;align-items:center;font-size:11px;font-weight:600;color:var(--text-muted);background:var(--chip-surface);border:1px solid var(--chip-border);border-radius:999px;padding:1px 8px;white-space:nowrap;}
.amc-jobrow__assignees.is-mine .amc-assignchip{color:var(--text);border-color:var(--border-strong);}
.amc-jobrow--compact .amc-jobrow__assignees{display:none;}
.amc-filterbar__mine{flex:none;}
/* Batch-assign dialog (assignment layer). */
.amc-assigndlg{width:min(520px,92vw);max-width:520px;}
.amc-assigndlg__title{font-size:18px;font-weight:700;color:var(--text);margin:0 0 4px;}
.amc-assigndlg__hint{font-size:13px;margin:0 0 12px;}
.amc-assigndlg__loading{display:flex;align-items:center;gap:8px;color:var(--text-muted);font-size:14px;padding:10px 0;}
/* ASSIGN-UNASSIGN-001 — the Visit-level three-way assignment choice (VisitAssignmentChoice.tsx).
   Stacked full-width options, never a segmented strip: each one carries a sentence saying what it
   does, and "follow the job default" vs "nobody for this visit" must never read as the same gesture.
   min-height 44px is the tap-target law, not decoration. */
.amc-visitassign{display:flex;flex-direction:column;gap:10px;}
.amc-choice{display:flex;flex-direction:column;gap:8px;}
.amc-choice__opt{display:flex;flex-direction:column;align-items:flex-start;gap:3px;width:100%;min-height:44px;text-align:left;padding:11px 13px;border:1px solid var(--chip-border);border-radius:12px;background:var(--chip-surface);color:var(--text);cursor:pointer;}
.amc-choice__opt:hover:not(:disabled){border-color:var(--primary);}
.amc-choice__opt:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.amc-choice__opt:disabled{opacity:.55;cursor:default;}
.amc-choice__opt.is-selected{border-color:var(--primary);box-shadow:inset 0 0 0 1px var(--primary);}
.amc-choice__label{font-size:15px;font-weight:700;}
.amc-choice__help{font-size:12.5px;font-weight:400;line-height:1.35;}
.amc-visitassign__problem{margin:0;font-size:13px;font-weight:600;color:var(--destructive);}
.amc-assigndlg__body{display:flex;flex-direction:column;gap:14px;}
.amc-assigndlg__group{display:flex;flex-direction:column;gap:7px;}
.amc-assigndlg__grouphead{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--text-muted);margin:0;}
.amc-assigndlg__actions{display:flex;justify-content:flex-end;gap:10px;margin-top:16px;}
.amc-stickybar__assign{flex:none;}
.amc-jobrow__desc{font-size:13.5px;color:var(--text);line-height:1.42;white-space:pre-wrap;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;}
.amc-jobrow__desc.is-expanded{-webkit-line-clamp:unset;overflow:visible;}
/* DF-015c + 2026-06-30 — the More/Less toggle rides the END of the clamped instructions' last line. The wrap
   is the positioning context; when CLAMPED (collapsed + actually overflowing) a right gutter is reserved on the
   instructions and the toggle is pinned into it at the bottom-right, so it adds NO extra row and overlaps no
   text (works on any row tint — no background-matched fade needed). Expanded → it flows inline beneath. */
.amc-jobrow__descwrap{position:relative;min-width:0;}
.amc-jobrow__descfull{display:contents;}
.amc-jobrow__sortdesc{display:none;}
.amc-jobrow__descwrap[data-clamped="yes"] .amc-jobrow__desc{padding-right:54px;}
.amc-jobrow__morelink{display:inline-flex;align-items:center;gap:3px;margin-top:2px;padding:3px 6px;border:none;background:none;color:var(--text-muted);font-size:12.5px;font-weight:700;cursor:pointer;border-radius:6px;line-height:1.1;}
.amc-jobrow__morelink:hover{color:var(--text);background:var(--chip-surface);}
.amc-jobrow__morelink:focus-visible{outline:2px solid var(--focus);outline-offset:-1px;}
/* Collapsed+overflowing: pin into the reserved gutter as a comfortable ≥44px-wide / ≥28px-tall tap target so it
   is hard to mis-tap into the row's own checkbox toggle (owner: the old caret's hit area was too small). */
.amc-jobrow__descwrap[data-clamped="yes"] .amc-jobrow__morelink{position:absolute;right:0;bottom:0;margin:0;min-width:48px;min-height:28px;justify-content:flex-end;}
/* Rich instructions render the canonical restricted-HTML (<p>/<br>/<strong>/<em>/<u>); neutralize the
   paragraph wrapper's default margins so multi-paragraph instructions stay dense. strong/em/u use
   the browser defaults (bold / italic / underline) — exactly the office's authored emphasis. */
.amc-jobrow__desc p{margin:0;}
.amc-jobrow__desc p + p{margin-top:3px;}
/* The measured clamp owns clipping and height. Its rich/plain content stays fully laid out in both
   directions so collapse is a true reverse instead of truncating the text before the wrapper travels. */
.amc-jobrow__descdisclose .amc-jobrow__desc{display:block;-webkit-line-clamp:unset;overflow:visible;padding-right:0;}
.amc-jobrow__notepreview{font-size:12px;color:var(--text-muted);font-style:italic;}
/* shared per-visit notes preview (dense row): one line per author. The body renders the restricted
   rich HTML (bold/italic/underline) accurately — it is NOT forced italic — while the author label is
   bold. p tags flow inline so a single-paragraph note stays on the author's line. */
.amc-jobrow__notes{display:flex;flex-direction:column;gap:1px;}
.amc-jobrow__noteauthor{font-style:normal;font-weight:700;color:var(--text);}
.amc-jobrow__notebody{font-style:normal;}
.amc-jobrow__notebody p{margin:0;display:inline;}
.amc-jobrow__notebody p + p{display:block;margin-top:2px;}
.amc-jobrow__foot{display:flex;flex-wrap:wrap;align-items:center;gap:2px 14px;padding:0 11px 2px 45px;}
.amc-jobrow--done .amc-jobrow__foot{padding-left:0;}
/* OFR-R5-B — trailing 2px removed; the strip's own button height carries the touch area. */
.amc-jobrow__foot.amc-jobrow__acts{gap:1px 3px;padding:0 11px 0;}
.amc-jobrow__more{font-size:12px;padding:3px 0;min-height:0;width:auto;} /* __notebtn/__undo/__editjob retired: POLISH-ICONS-001 made them icon buttons */
.amc-jobrow__when{color:var(--text-muted);}
.amc-jobrow__when{font-size:11.5px;}
.amc-jobrow__voiderr{font-size:11.5px;color:var(--destructive);}
.amc-jobrow__details{display:flex;flex-wrap:wrap;gap:5px 8px;padding:0 11px 9px 45px;}
.amc-jobrow--done .amc-jobrow__details{padding-left:0;}
.amc-jobrow__detailbit{font-size:11px;color:var(--text-muted);background:var(--chip-surface);border:1px solid var(--chip-border);border-radius:6px;padding:1px 8px;}

/* Aggregate drill-down operational rows (customer + service location). These deliberately reuse the
   Mark Complete information hierarchy without importing its mutation/freshness state machine. */
/* N8: .amc-oprow COMPOSES .amc-jobrow (OperationalSummaryCard.tsx renders className="amc-jobrow
   amc-oprow"), so it inherits the seam and all three rail slots with zero per-surface CSS, and it
   carries data-hl so the five tints apply here too. No drilldown-specific seam rule is needed — a
   per-surface patch is exactly what would leave the hole open on the next surface. */
.amc-oplist{margin:0;padding:0;list-style:none;}
.amc-oprow__body{display:flex;flex-direction:column;gap:5px;min-width:0;padding:9px 11px 10px;}
.amc-oprow__link{display:inline-block;line-height:1.35;}
button.amc-oprow__link{width:auto;min-width:44px;min-height:44px;max-width:100%;padding:0;border:0;background:transparent;text-align:left;white-space:normal;}
.amc-oprow__context{font-size:12.5px;color:var(--text-muted);overflow-wrap:anywhere;}
.amc-oprow__noinstructions{font-size:13px;line-height:1.42;color:var(--text-faint);font-style:italic;}
/* SORT-002 per-row controls (the stop drilldown's within-stop order nudges). Shipped inline while this
   file sat 8 lines from its budget; the recorded +200 raise is now taken, so the rule lives here. */
.amc-oprow__actions{display:flex;gap:8px;flex-wrap:wrap;}
.amc-oprow .amc-jobrow__details{padding:2px 0 0;}
/* IC-R7 F3 projected occurrence (law: docs/architecture/aggregate-drilldown-operational-rows.md) — real
   schedule, not a record yet: keeps the row shape, loses solidity. Never a reserved flag colour, or an
   ordinary future mow would read as owed/failed work. */
.amc-oprow[data-projected="yes"]{border-style:dashed;background:color-mix(in srgb, var(--surface-2) 55%, transparent);}
.amc-oprow[data-projected="yes"] .amc-oprow__link{color:var(--text-muted);}.amc-oprow[data-projected="yes"] .amc-jobrow__meta{font-style:italic;}

/* submit bar — appears on first check, FIXED to the visible viewport bottom (a sticky;bottom:0 last
   child sits below the fold until you scroll down, which fails "visible without scrolling"), centered
   to the page width, Evergreen accent. The page reserves padding-bottom so content isn't hidden. */
.amc-stickybar{position:fixed;bottom:0;left:50%;transform:translateX(-50%);z-index:30;width:min(820px,100%);background:var(--surface);border-top:2px solid var(--positive);border-radius:14px 14px 0 0;padding:11px 14px calc(11px + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:9px;box-shadow:0 -12px 28px -18px rgba(0,0,0,.55);}
.amc-stickybar__row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.amc-stickybar__status{display:flex;align-items:center;gap:10px;flex-wrap:wrap;min-width:0;}
.amc-stickybar__count{font-size:14px;font-weight:700;color:var(--text);}
.amc-stickybar__note{width:auto;flex:none;}
.amc-stickybar__clear{width:auto;flex:none;}
.amc-stickybar__highlight{width:auto;flex:none;}
.amc-stickybar__submit{flex:1;min-width:0;min-height:48px;}
.amc-draftbar__save{font-size:13px;display:inline-flex;align-items:center;gap:5px;color:var(--text-muted);}
.amc-draftbar__save--ok{color:var(--positive);font-size:15px;}
.amc-draftbar__save--err{color:var(--destructive);}
.amc-draftbar__retry{display:inline;width:auto;min-height:0;padding:0 0 0 4px;font-size:12.5px;}

/* stale / freshness — a CENTERED BLOCKING refresh (reuses .amc-overlay + .amc-confirm). The single
   Refresh action stretches full width so it's the obvious (and only) way forward. */
.amc-stalemodal__refresh{width:100%;}

/* submit result summary (Evergreen = complete) with a batch-level undo */
.amc-submitresult{display:flex;align-items:flex-start;gap:11px;border-radius:var(--radius);padding:13px 14px;background:var(--positive-surface);border:1px solid var(--positive-border);color:var(--positive);flex-wrap:wrap;}
.amc-submitresult__glyph{font-weight:700;flex:none;font-size:16px;}
.amc-submitresult__body{flex:1;min-width:140px;font-size:14px;line-height:1.45;}
.amc-submitresult__body .amc-meta{color:var(--positive);opacity:.85;}
.amc-submitresult__actions{display:flex;align-items:center;gap:10px;flex:none;}
.amc-submitresult__undo{width:auto;}
.amc-submitresult__dismiss{width:auto;color:var(--positive);}

/* note editor sheet */
.amc-noteeditor{max-width:560px;margin:0 auto;}
.amc-noteeditor__title{margin:0;font-size:18px;font-weight:700;}
.amc-noteeditor__subtitle{margin:4px 0 0;font-size:13px;}
.amc-noteeditor__input{width:100%;min-height:120px;margin-top:12px;}
.amc-noteeditor__actions{display:flex;gap:10px;margin-top:14px;}
.amc-noteeditor__actions .amc-btn{flex:1;}
@media (min-width:880px){.amc-overlay--bottom .amc-noteeditor{border-radius:var(--radius-lg);margin-bottom:18vh;}}
/* shared per-visit notes sheet (Phase 5.3): teammates' notes read-only above your own editor */
.amc-notelist{display:flex;flex-direction:column;gap:8px;margin-top:10px;}
.amc-notecard{border:1px solid var(--chip-border);background:var(--chip-surface);border-radius:8px;padding:8px 10px;}
.amc-notecard__head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:3px;}
.amc-notecard__author{font-size:12px;font-weight:700;color:var(--text);}
.amc-notecard__del{font-size:12px;width:auto;min-height:0;padding:0;color:var(--destructive);}
.amc-notecard__body{font-size:13px;color:var(--text);}
.amc-notecard__body p{margin:0;}
.amc-noteeditor__own{margin-top:14px;}
.amc-noteeditor__delown{flex:0 0 auto;}

/* job editor sheet (Phase 5.2A — manager/owner edit of instructions/highlight/zone + pause) */
.amc-jobeditor{max-width:560px;margin:0 auto;}
.amc-jobeditor__title{margin:0;font-size:18px;font-weight:700;}
.amc-jobeditor__subtitle{margin:4px 0 0;font-size:13px;}
.amc-jobeditor__label{display:block;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);margin:14px 0 6px;}
.amc-jobeditor__input{width:100%;min-height:96px;}
/* lightweight rich-text editor (contentEditable + B/I/U toolbar); server canonicalizes the markup */
.amc-richtext__toolbar{display:flex;gap:6px;margin:6px 0;}
.amc-richtext__btn{flex:none;width:44px;min-height:44px;border:1px solid var(--field-border);border-radius:8px;background:var(--surface);color:var(--text);font-size:15px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;}
.amc-richtext__btn:hover{background:var(--chip-surface);}
.amc-richtext__btn:focus-visible{outline:2px solid var(--focus);outline-offset:1px;}
.amc-richtext__editor{overflow:auto;white-space:pre-wrap;width:100%;box-sizing:border-box;}
.amc-richtext__editor:empty:before{content:attr(data-placeholder);color:var(--text-faint);}
.amc-richtext__editor:focus-visible{outline:2px solid var(--focus);outline-offset:-1px;}
.amc-richtext__editor p{margin:0;}
.amc-richtext__editor p + p{margin-top:4px;}
.amc-jobeditor__field{min-width:0;margin:4px 0 0;padding:0;border:0;}
.amc-jobeditor__field>legend.amc-jobeditor__label{padding-inline:0;}
.amc-jobeditor__subfield{margin-top:4px;}
.amc-jobeditor__zone{width:100%;}
.amc-jobeditor__toggle{display:flex;align-items:flex-start;gap:9px;margin-top:16px;font-size:14px;line-height:1.4;cursor:pointer;}
.amc-jobeditor__toggle input{margin-top:2px;width:18px;height:18px;flex:none;}
.amc-jobeditor__pausehint{display:inline;}
.amc-jobeditor__error{margin-top:14px;}
.amc-jobeditor__actions{display:flex;gap:10px;margin-top:16px;}
.amc-jobeditor__actions .amc-btn{flex:1;}
/* "Reschedule job" expandable section (Phase 5.3 Part C) — collapsed by default, scheduling fields */
.amc-jobeditor__reschedtoggle{width:auto;min-height:0;padding:0;font-size:13px;font-weight:700;}
.amc-reschedule{margin-top:8px;padding:10px 12px;border:1px solid var(--chip-border);border-radius:8px;background:var(--chip-surface);}
.amc-reschedule__warn{margin:0 0 8px;font-size:12.5px;}
.amc-reschedule__current{display:flex;flex-wrap:wrap;gap:4px 16px;margin:0 0 8px;}
.amc-reschedule__current div{display:flex;gap:6px;}
.amc-reschedule__current dt{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);margin:0;}
.amc-reschedule__current dd{font-size:12.5px;color:var(--text);margin:0;}
.amc-reschedule__hint{display:block;font-size:12px;margin-top:4px;}
/* DF-012 — the entry to the full ScheduleEditDialog from the work-list job editor. */
.amc-reschedule__advanced{margin-top:10px;width:100%;font-size:13px;}
@media (min-width:880px){.amc-overlay--bottom .amc-jobeditor{border-radius:var(--radius-lg);margin-bottom:12vh;}}
/* DF-018b — the edit-SCOPE chooser (job vs this visit only) + the per-visit override sheet. */
.amc-editscope__title{margin:0;font-size:18px;font-weight:700;}
.amc-editscope__subtitle{margin:2px 0 12px;font-size:13px;}
.amc-editscope__choice{display:flex;align-items:flex-start;gap:12px;width:100%;text-align:left;margin:0 0 10px;padding:14px;border:1px solid var(--chip-border);border-radius:12px;background:var(--chip-surface);color:var(--text);cursor:pointer;}
.amc-editscope__choice:hover{border-color:var(--primary);}
.amc-editscope__choice:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.amc-editscope__choiceicon{flex:0 0 auto;font-size:20px;line-height:1.2;width:28px;text-align:center;}
.amc-editscope__choicebody{display:flex;flex-direction:column;gap:2px;}
.amc-editscope__choicehead{font-size:15px;font-weight:700;}
.amc-editscope__choicesub{font-size:12.5px;}
.amc-editscope__badge{font-size:12px;font-weight:600;color:var(--primary);}
.amc-editscope__actions{display:flex;margin-top:4px;}
.amc-editscope__actions .amc-btn{flex:1;}
@media (min-width:880px){.amc-overlay--bottom .amc-editscope{border-radius:var(--radius-lg);margin-bottom:16vh;}}
.amc-visitoverride__note{margin:0 0 10px;font-size:12.5px;}
.amc-jobeditor__overridden{font-size:12px;font-weight:600;color:var(--primary);}
.amc-visitoverride__reset{flex:0 0 auto;}
/* CFLABEL-001 second surface — the missed label's revert block in the pencil editor; shows the exact badge the row wears. */
.amc-visitoverride__missed{display:flex;flex-direction:column;align-items:flex-start;gap:6px;}.amc-visitoverride__missednote{margin:0;font-size:12.5px;}
/* DF-018b — the row badge: this visit's instructions/highlight deviate from the job. */
.amc-jobrow__overridechip{display:inline-block;margin-top:4px;padding:1px 8px;border:1px solid var(--chip-border);border-radius:999px;background:var(--chip-surface);color:var(--text-muted);font-size:11px;font-weight:700;}

/* canonical Service Locations Sort List (Phase 5.3 Part D) */
.amc-sortlist{margin:8px 0 14px;border:1px solid var(--chip-border);border-radius:10px;padding:8px 10px;background:var(--surface);}
.amc-sortlist__toggle{width:auto;min-height:0;padding:0;font-size:13px;font-weight:700;}
.amc-sortlist__body{margin-top:8px;}
.amc-sortlist__archived{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--text-muted);margin-bottom:8px;}
.amc-sortlist__rows{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px;}
.amc-sortrow{display:flex;align-items:center;gap:8px;padding:4px 6px;border:1px solid var(--chip-border);border-radius:8px;background:var(--chip-surface);}
.amc-sortrow--archived{opacity:.6;}
.amc-sortrow__rank{font-size:12px;color:var(--text-muted);min-width:22px;}
.amc-sortrow__name{flex:1;min-width:0;font-size:13px;color:var(--text);display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
.amc-sortrow__hidden{font-size:11px;}
.amc-sortrow__moves{display:flex;gap:4px;flex:none;}
.amc-sortrow__moves .amc-iconbtn{width:34px;min-height:34px;}

/* per-visit "Move to day" (Phase 5.3 Part D — one-time visit move within the week) */
.amc-jobrow__moveday{display:flex;flex-wrap:wrap;gap:4px;padding:4px 11px 8px 45px;}
.amc-jobrow__moveday .amc-btn{width:auto;min-height:34px;padding:2px 8px;font-size:12px;}

/* ===== Jobs Config Grid (Phase 5.4, JOBS-GRID-001) — dense spreadsheet-style admin config =====
   Deliberately NOT the Mark Complete card styling: column headers, compact rows, sticky header,
   horizontal scroll, drag-resizable columns. Desktop/admin is the priority; mobile scrolls. */
.amc-cfg-page{max-width:calc(100vw - 24px);}
.amc-cfg-head__actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
.amc-cfg-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;}

/* toolbar: global search + Wrap text + column chooser + reset (per-column filters live in the headers) */
.amc-cfg-toolbar{display:flex;flex-direction:column;gap:6px;}
.amc-cfg-toolbar__row{display:flex;flex-wrap:wrap;align-items:flex-end;gap:8px;}
.amc-cfg-toolbar__summary{font-size:12px;}
.amc-cfg-search{flex:1 1 240px;min-width:180px;min-height:38px;}
.amc-cfg-fdd__opt{display:flex;align-items:center;gap:7px;font-size:13px;padding:4px 4px;cursor:pointer;}
.amc-cfg-fdd__opt input{width:16px;height:16px;flex:none;}
.amc-cfg-cols{position:relative;}
.amc-cfg-cols__btn{min-height:38px;width:auto;cursor:pointer;}
.amc-cfg-cols__panel{position:absolute;top:calc(100% + 4px);right:0;z-index:40;background:var(--surface);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow-pop);padding:10px;display:grid;grid-template-columns:1fr 1fr;gap:2px 14px;min-width:264px;}
.amc-cfg-cols__opt{display:flex;align-items:center;gap:7px;font-size:13px;padding:4px 4px;cursor:pointer;}
.amc-cfg-cols__opt input{width:16px;height:16px;flex:none;}
.amc-cfg-wrap{display:inline-flex;align-items:center;gap:7px;min-height:38px;font-size:13px;color:var(--text);cursor:pointer;white-space:nowrap;}
.amc-cfg-wrap input{width:16px;height:16px;flex:none;}
.amc-cfg-reset{min-height:38px;width:auto;padding:0 6px;}

/* the grid itself — the gridwrap is the scroll container (sticky header rides it) */
.amc-cfg-gridwrap{overflow:auto;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);}
.amc-cfg-gridwrap:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
.amc-cfg-grid{border-collapse:separate;border-spacing:0;table-layout:fixed;width:100%;font-size:12.5px;color:var(--text);}
@media (max-width:640px){.amc-cfg-grid{min-width:720px;}}
.amc-cfg-grid thead th{position:sticky;top:0;z-index:2;background:var(--surface-2);border-bottom:1.5px solid var(--border-strong);padding:0;text-align:left;vertical-align:bottom;}
.amc-cfg-grid__th{position:relative;}
/* header is a button that opens this column's filter; a funnel icon lights up when the column is filtered */
.amc-cfg-grid__hbtn{display:flex;align-items:center;justify-content:space-between;gap:6px;width:100%;min-height:0;padding:7px 15px 7px 10px;background:none;border:0;border-radius:0;color:var(--text-muted);font:inherit;font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;text-align:left;cursor:pointer;}
.amc-cfg-grid__hbtn:hover{color:var(--text);background:var(--surface);}
.amc-cfg-grid__hbtn[data-filtered="true"]{color:var(--text);}
.amc-cfg-grid__th--right .amc-cfg-grid__hbtn{flex-direction:row-reverse;}
.amc-cfg-grid__hlabel{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.amc-cfg-filticon{flex:none;display:inline-flex;align-items:center;color:var(--text-faint);opacity:.5;}
.amc-cfg-filticon.is-active{color:var(--selected);opacity:1;}
.amc-cfg-grid__resize{position:absolute;top:0;right:0;width:9px;height:100%;cursor:col-resize;touch-action:none;}
.amc-cfg-grid__resize:hover{background:var(--selected-soft);}
.amc-cfg-grid tbody td{padding:3px 10px;border-bottom:1px solid var(--divider);vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.amc-cfg-grid tbody tr[data-job-id]{height:49px;}
.amc-cfg-grid tbody tr:last-child td{border-bottom:none;}
/* zebra rows (by display position, so striping survives filtering); paused beats zebra; hover beats both */
.amc-cfg-grid tbody tr:nth-child(even) td{background:var(--surface-2);}
.amc-cfg-grid tbody tr.amc-cfg-grid__row--paused td{background:var(--warning-surface);color:var(--text-faint);}
.amc-cfg-grid tbody tr:hover td{background:var(--chip-surface);}
.amc-cfg-grid__row--paused .amc-cfg-celltext{color:var(--text-faint);}
/* "Wrap text" uses the same measured disclosure as every other expanding surface. Cell content stays
   fully laid out in both directions; the wrapper owns the 1-line / 2-line clip and reversible height. */
.amc-cfg-cell-disclose .amc-disclose__content{white-space:normal;overflow:visible;overflow-wrap:anywhere;}
.amc-cfg-cell-disclose .amc-cfg-celltext{white-space:normal;overflow:visible;text-overflow:clip;}
.amc-cfg-cell-disclose .amc-cfg-instr{display:block;-webkit-line-clamp:unset;overflow:visible;}
.amc-cfg-namecell>.amc-cfg-cell-disclose,.amc-cfg-namecell>.amc-cfg-cellaction{flex:1 1 auto;min-width:0;}
.amc-cfg-grid__td--right{text-align:right;}
/* per-column header filter popover (fixed panel, escapes the grid's overflow) */
.amc-cfg-colfilter-panel{min-width:200px;max-width:300px;}
.amc-cfg-colfilter__head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:6px;}
.amc-cfg-colfilter__title{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.amc-cfg-colfilter__clear{width:auto;min-height:0;padding:0;font-size:12px;flex:none;}
.amc-cfg-colfilter__opts{display:flex;flex-direction:column;gap:2px;max-height:288px;overflow:auto;overscroll-behavior:contain;}
.amc-cfg-colfilter__empty{font-size:12px;margin:2px 2px;}
.amc-cfg-colfilter__input{width:100%;min-height:34px;}
.amc-cfg-colfilter__hint{font-size:11px;margin:6px 0 0;}
.amc-cfg-terms{list-style:none;margin:7px 0 0;padding:0;display:flex;flex-direction:column;gap:4px;max-height:208px;overflow:auto;overscroll-behavior:contain;}
.amc-cfg-term{display:flex;align-items:center;justify-content:space-between;gap:8px;background:var(--chip-surface);border:1px solid var(--chip-border);border-radius:8px;padding:2px 3px 2px 9px;font-size:12.5px;}
.amc-cfg-term__text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.amc-cfg-term__del{flex:none;display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;min-height:0;padding:0;border:0;border-radius:6px;background:none;color:var(--text-muted);cursor:pointer;}
.amc-cfg-term__del:hover{background:var(--surface);color:var(--destructive);}
.amc-cfg-grid__td--wrap{white-space:normal;}
.amc-cfg-grid__td--center{text-align:center;}

/* inline cell editors. NOTE: this is the DESKTOP admin config grid (spreadsheet density is the explicit
   milestone priority — compact rows, no large cards), so cell controls are intentionally denser than the
   44px field-UI touch-target contract; mobile degrades to horizontal scroll. */
.amc-cfg-celltext{overflow:hidden;text-overflow:ellipsis;}
.amc-cfg-cellempty{color:var(--text-faint);}
.amc-cfg-celledit{display:block;width:100%;min-height:28px;text-align:left;background:none;border:1px solid transparent;border-radius:6px;padding:3px 6px;color:var(--text);cursor:text;font:inherit;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.amc-cfg-celledit:hover,.amc-cfg-celledit:focus-visible{border-color:var(--field-border);background:var(--surface);}
.amc-cfg-celledit:disabled{cursor:default;opacity:.6;}
/* Name cell: the editable/read name plus a per-row drill-down link to the job detail page. The link is a
   separate <a> (not the inline-edit target / drag handle), always visible but subtle so it works on touch
   too, brightening on hover/focus. */
.amc-cfg-namecell{display:flex;align-items:center;gap:2px;min-width:0;}
.amc-cfg-namecell>.amc-cfg-celledit,.amc-cfg-namecell>.amc-cfg-celltext{flex:1 1 auto;min-width:0;}
.amc-cfg-drill{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:6px;color:var(--text-faint);text-decoration:none;}
.amc-cfg-drill:hover,.amc-cfg-drill:focus-visible{color:var(--focus);background:var(--surface);}
.amc-cfg-cellinput{display:block;width:100%;min-height:28px;padding:3px 6px;font:inherit;border:1.5px solid var(--focus);border-radius:6px;background:var(--surface);color:var(--text);}
.amc-cfg-cellinput--multi{height:auto;max-height:168px;overflow:auto;resize:none;line-height:1.5;white-space:pre-wrap;}
.amc-cfg-glyph{color:var(--text-muted);}
.amc-cfg-crm{font-size:11px;color:var(--text-muted);}

/* Active pill (green = active, gray = paused) — not a checkbox */
.amc-cfg-pill{display:inline-block;font-size:11px;font-weight:700;line-height:1;padding:4px 10px;border-radius:999px;border:1px solid transparent;white-space:nowrap;}
.amc-cfg-pill--active{background:var(--positive-surface);border-color:var(--positive-border);color:var(--positive);}
.amc-cfg-pill--done{background:color-mix(in srgb, var(--text-muted) 13%, var(--surface));border-color:var(--border-strong);color:var(--text);}
.amc-cfg-pill--paused{background:var(--warning-surface);border-color:var(--border-strong);color:var(--text-muted);}
.amc-cfg-pill--review{background:var(--surface-2);border-color:var(--border-strong);color:var(--text-muted);}
.amc-cfg-pill--btn{cursor:pointer;min-height:26px;font:inherit;font-size:11px;font-weight:700;}
/* Round 2 (2D): the Done → Active reactivation dialog's new-date field. */
.amc-cfg-reanchor__label{display:flex;flex-direction:column;gap:4px;margin-top:12px;font-size:13px;color:var(--text-muted);}
.amc-cfg-reanchor__label input{max-width:200px;}
.amc-cfg-pill--btn:hover{filter:brightness(.97);}
.amc-cfg-pill--btn:disabled{opacity:.6;cursor:default;}

/* highlight: swatch-only cell + click-to-open palette popover (fixed panel escapes cell clipping) */
.amc-cfg-swatchcell{display:inline-flex;align-items:center;}
.amc-cfg-pop{position:relative;display:inline-flex;}
.amc-cfg-pop__trigger{display:inline-flex;align-items:center;justify-content:center;min-height:26px;padding:2px 7px;background:none;border:1px solid transparent;border-radius:6px;cursor:pointer;color:var(--text);font:inherit;}
.amc-cfg-pop__trigger:hover,.amc-cfg-pop__trigger:focus-visible{border-color:var(--field-border);background:var(--surface);}
.amc-cfg-pop__trigger:disabled{opacity:.6;cursor:default;}
.amc-cfg-pop__backdrop{position:fixed;inset:0;z-index:55;background:transparent;}
.amc-cfg-pop__panel{position:fixed;z-index:56;background:var(--surface);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow-pop);padding:8px;}
.amc-cfg-palette{display:grid;grid-template-columns:repeat(3,auto);gap:6px;}
.amc-cfg-swatchbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:1.5px solid var(--border-strong);border-radius:8px;background:var(--surface);cursor:pointer;padding:0;}
.amc-cfg-swatchbtn:hover{border-color:var(--field-border);}
.amc-cfg-swatchbtn.is-current{border-color:var(--focus);box-shadow:0 0 0 2px var(--selected-soft);}
.amc-cfg-swatchbtn .amc-hl{width:18px;height:18px;}

/* weekday reschedule popover */
.amc-cfg-pop__panel--wd{min-width:188px;}
.amc-cfg-wd__warn{font-size:11px;margin:0 0 6px;line-height:1.35;}
.amc-cfg-wd__opts{display:flex;flex-direction:column;gap:2px;}
.amc-cfg-wd__opt{text-align:left;background:none;border:1px solid transparent;border-radius:6px;padding:5px 8px;font:inherit;font-size:13px;cursor:pointer;color:var(--text);}
.amc-cfg-wd__opt:hover{background:var(--surface-2);}
.amc-cfg-wd__opt.is-current{font-weight:700;color:var(--positive);}

/* instructions: the measured boundary reveals two integral lines; click opens an INLINE rich editor (no toolbar) */
.amc-cfg-instrbtn{display:block;width:100%;text-align:left;background:none;border:1px solid transparent;border-radius:6px;padding:3px 6px;color:var(--text);cursor:pointer;font:inherit;}
.amc-cfg-instrbtn:hover,.amc-cfg-instrbtn:focus-visible{border-color:var(--field-border);background:var(--surface);}
.amc-cfg-instr{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.38;}
.amc-cfg-instr p{margin:0;}
.amc-cfg-instr p + p{margin-top:2px;}
.amc-cfg-instredit{min-height:46px;max-height:168px;overflow:auto;font-size:12.5px;line-height:1.4;}
/* Interactive measured cells keep rich/block content OUTSIDE the button. One empty labelled button
   overlays the disclosure exactly, so its geometric centre can never fall below a closed clip. */
.amc-cfg-cellaction{position:relative;width:100%;min-width:0;}
.amc-cfg-cellaction__display{min-height:28px;padding:3px 6px;white-space:normal;overflow:visible;overflow-wrap:anywhere;pointer-events:none;}
.amc-cfg-cellaction__display--instructions{min-height:42px;}
.amc-cfg-cellaction>.amc-cfg-cellaction__hit{position:absolute;inset:0;z-index:1;display:block;width:100%;height:100%;min-height:0;padding:0;overflow:hidden;background:transparent;}
.amc-cfg-cellaction>.amc-cfg-cellaction__hit:hover,.amc-cfg-cellaction>.amc-cfg-cellaction__hit:focus-visible{background:transparent;}
.amc-cfg-cellaction[data-disabled="yes"]{opacity:.6;}
.amc-cfg-cellaction>.amc-cfg-cellaction__hit:disabled{opacity:1;}
.amc-cfg-sortlist{margin-top:16px;}
@media (max-width:720px){
  .amc-cfg-gridwrap{max-height:none;}
  .amc-cfg-cols__panel{grid-template-columns:1fr;left:0;right:auto;}
}

/* ===== Service Locations / Route Order page (Phase 5.5, ROUTE-ORDER-001) — the dedicated master route
   order surface; replaces the interim Sort List panel inside Jobs Config. Dense, desktop-first; no map.
   This is a manager/owner PLANNING surface (like the Jobs Config Grid): reorder controls are a touch
   denser than the 44px field-UI contract so a long route list stays scannable; they keep visible focus +
   text labels, and mobile degrades to horizontal scroll. */
/* Phase 5.8 (owner round 2): rebuilt on the Jobs Config Grid template — dense table, sticky toolbar
   (Sort mode + Show archived on top), Customer + Service-location columns (label WITH the address),
   drag-only reorder (no #/▲▼/position input). Mobile = horizontal scroll, like the grid. */
.amc-route-page{max-width:calc(100vw - 24px);}
.amc-route-page__actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
.amc-route-page__toolbar{margin-bottom:10px;}
.amc-route-page__sort,.amc-cfg-toolbar__sort{min-width:84px;}
.amc-route-page__archived{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text-muted);cursor:pointer;white-space:nowrap;}
.amc-route-page__archived input{width:16px;height:16px;flex:none;}
/* Owner finding #10 — the page-level nav/refresh actions moved OUT of their own amc-page__head row and
   into this toolbar's row, so the header spends one slim strip instead of a head row + a separate row.
   margin-left:auto keeps Sort/Show archived left-anchored and the nav actions right-anchored while both
   still wrap onto their own line on narrow widths (amc-cfg-toolbar__row already wraps). */
.amc-route-page__toolbar-nav{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-left:auto;}
/* Owner finding #10 — the CRM location mapping card collapses to ONE summary line by default
   (amc-cfg-crmcard__summary) and discloses its full existing content on demand via the shared M-10
   MeasuredDisclosure boundary (amc-disclose, defined near the SORT-004 section below). Nothing inside
   the disclosed body is new; only the collapsed state is. */
.amc-cfg-crmcard{padding:8px 14px;gap:0;}
.amc-cfg-crmcard__h{margin:0;}
.amc-cfg-crmcard__summary{display:flex;align-items:center;gap:6px;width:100%;padding:2px 0;background:none;border:0;font:inherit;font-size:13px;color:var(--text);cursor:pointer;text-align:left;}
.amc-cfg-crmcard__label{color:var(--text-muted);}
.amc-cfg-crmcard__value{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:38ch;}
.amc-cfg-crmcard__action{color:var(--positive);font-weight:600;}
/* FID-109 — the /request-access listing state, on the same one summary line (never a second row). */
.amc-cfg-crmcard__vis{color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
.amc-cfg-crmcard__chevron{margin-left:auto;color:var(--text-faint);}
.amc-cfg-crmcard__body{padding-top:10px;}
/* Owner finding #10 — the "← Back to the app" link is a SERVER-rendered sibling of the React mount root
   (src/routes/app-jobs.ts / app-service-locations.ts, both outside this lane's file grant), sitting in
   the same framed flex column above the page and taking its own full line before any compaction here.
   This narrowly scoped :has() selector (matched only by the anchor immediately preceding OUR two mount
   roots — never the work list's or QC review's identical link) shrinks its footprint without touching
   those route files. Fully folding it INTO the sticky toolbar per the target design still needs an edit
   there; flagged in the row-10 notes as out of this lane's scope. FID-117 (2026-09-23) did that edit for Route
   Order: its anchor now sits INSIDE #amc-service-locations-root and React replaces it with the toolbar Back, so
   the former has()-scoped display:none rule on the anchor before that root (a Back-less pre-mount gap, and two Backs
   on engines without :has()) is gone. */
.amc-canvas > a.amc-btn--link:has(+ #amc-jobs-root){margin:4px 14px 0 !important;font-size:12.5px;}
.amc-route-wrap{overflow:auto;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);}
.amc-route{border-collapse:separate;border-spacing:0;table-layout:fixed;width:100%;min-width:640px;font-size:12.5px;color:var(--text);}
.amc-route thead th{position:sticky;top:0;z-index:2;background:var(--surface-2);border-bottom:1.5px solid var(--border-strong);padding:7px 12px;text-align:left;font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--text-muted);white-space:nowrap;}
.amc-route__col-jobs{width:60px;}
.amc-route__th-jobs{text-align:right;}
.amc-route tbody td{padding:5px 12px;border-bottom:1px solid var(--divider);vertical-align:middle;}
.amc-route tbody tr:last-child td{border-bottom:none;}
.amc-route tbody tr:nth-child(even) td{background:var(--surface-2);}
.amc-route tbody tr:hover td{background:var(--chip-surface);}
.amc-route__row--archived td{opacity:.6;}
/* The stop cell stays a plain table cell so it fills the row height (zebra band + column alignment);
   the flex layout of its contents lives on an inner wrapper. A flex td leaves the tallest sibling cell
   (the sort-mode weekday select) taller than the flex cell, so the per-td zebra band was short and the
   lighter container surface showed through as pale blocks straddling rows (audit item 1.2). */
.amc-route__stop{min-width:0;}
.amc-route__stopinner{display:flex;align-items:center;gap:6px;flex-wrap:wrap;min-width:0;}
.amc-route__addr{overflow:hidden;text-overflow:ellipsis;}
.amc-route__hidden{font-size:11px;}
.amc-route__jobs{text-align:right;font-variant-numeric:tabular-nums;color:var(--text-muted);}
.amc-route__th-weekday{width:88px;}
.amc-route__grouphead{display:table-cell;background:var(--divider-band-surface);font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--divider-band-foreground);padding:0;border-top:1.5px solid var(--border-strong);}
.amc-route__grouphead .amc-muted,.amc-cfg-grid__grouphead .amc-muted{color:inherit;opacity:.76;}
.amc-route__weekday{white-space:nowrap;}
.amc-route__weekdaysel{min-height:34px;padding:2px 6px;font:inherit;font-size:12.5px;border:1px solid var(--field-border);border-radius:6px;background:var(--surface);color:var(--text);}
.amc-route__weekdaysel:disabled{opacity:.6;}
.amc-route__weekday[data-sort-visible="false"] .amc-route__weekdaysel,.amc-route__movebtn[data-sort-visible="false"]{visibility:hidden;pointer-events:none;}
/* Phase 5.6 — work-list sort mode */
.amc-mcpage__sortbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:6px 0;}
.amc-sortmode{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.amc-sortmode__select{min-height:36px;padding:2px 8px;font:inherit;border:1px solid var(--field-border);border-radius:6px;background:var(--surface);color:var(--text);}
.amc-sortmode__hint{flex-basis:100%;font-size:12px;margin:2px 0 0;}
.amc-jobrow__reorder{display:inline-flex;gap:4px;margin-right:6px;}
.amc-jobrow__reorderbtn{width:36px;height:36px;min-height:36px;}
.amc-clarify__actions{flex-direction:column;align-items:stretch;gap:8px;}
@media (max-width:720px){
  .amc-route-wrap{max-height:none;}
}

/* Phase 5.7 — multi-week range work list + cross-week schedule editor */
.amc-rangebanner{margin:8px 0;}
.amc-weekband{margin:14px 0 4px;padding:5px 10px;border-radius:6px;background:var(--surface-2);border:1px solid var(--chip-border);font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);}
.amc-filterrow__daterange{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;color:var(--text-muted);}
.amc-filterrow__date{min-height:34px;padding:2px 6px;font:inherit;border:1px solid var(--field-border);border-radius:6px;background:var(--surface);color:var(--text);}
.amc-filterrow__rangehint{display:block;flex-basis:100%;font-size:12px;margin-top:4px;}
/* N6.1 (ic-r7 finding 4a/4c) — the period pair STAGES; this row is its one app-owned commit boundary.
   It mounts only while a change is outstanding, so the resting filter bar keeps its measured height. */
.amc-filterrow__apply{display:flex;flex-wrap:wrap;align-items:center;gap:8px;flex-basis:100%;margin-top:6px;padding:6px 8px;border:1px solid var(--chip-border);border-radius:8px;background:var(--chip-surface);}
.amc-filterrow__applybtn{margin-left:auto;}
/* Cadence cell becomes the schedule-edit trigger in the jobs grid */
.amc-cfg-schededit{cursor:pointer;}
/* Schedule edit dialog (cadence / anchor / service date) */
.amc-schededit{max-width:460px;width:calc(100vw - 32px);}
.amc-schededit__subtitle{margin:0 0 10px;font-size:13px;}
.amc-schededit__modes{display:flex;gap:8px;margin:0 0 12px;}
.amc-schededit__current{display:flex;flex-wrap:wrap;gap:4px 16px;margin:0 0 12px;padding:10px 12px;border:1px solid var(--chip-border);border-radius:8px;background:var(--chip-surface);}
.amc-schededit__current div{display:flex;gap:6px;}
.amc-schededit__current dt{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);margin:0;}
.amc-schededit__current dd{font-size:12.5px;color:var(--text);margin:0;}
.amc-schededit__field{display:block;margin:0 0 12px;}
.amc-schededit__label{display:block;font-size:12px;font-weight:700;margin-bottom:4px;}
.amc-schededit__field .amc-field{width:100%;}
.amc-schededit__hint{display:block;font-size:12px;margin-top:4px;}
.amc-schededit__effweek{padding-top:10px;border-top:1px solid var(--field-border);}
.amc-schededit__preview{margin:0 0 12px;padding:10px 12px;border:1px solid var(--positive-border);border-radius:8px;background:var(--positive-surface);font-size:13px;}
.amc-schededit__preview p{margin:4px 0 0;}
.amc-schededit__error{margin:0 0 12px;}
.amc-schededit__actions{display:flex;gap:10px;justify-content:flex-end;}
@media (max-width:720px){
  .amc-schededit__actions{flex-direction:column-reverse;}
  .amc-schededit__actions .amc-btn{width:100%;}
}

/* ===== Phase 5.8 — shared drag-and-drop sorting (Service Locations, Jobs Config, Operations) =====
   ONE interaction across the three sorting surfaces (powered by @dnd-kit). The grip handle is the only
   drag activator, exposed ONLY in Sort mode; the lifted-row + reflow feedback is CSS-only (no device
   API). Reuses the semantic tokens — no raw hex; reserved colours (green/fuchsia/orange/Citrus) are
   untouched. Target geometry is surface-specific: touch/card grips keep the exclusive 44px default;
   fine-pointer desktop grids opt into the owner-approved ~24px AA floor without changing row pitch. */
/* SORT-003/P2 — the BUTTON is always the real, exclusive target and adjacent targets never overlap.
   The drawn affordance is the smaller inner .amc-drag__grip box. Keyboard drag + the sole activator stay
   on the button; focus/hover/press feedback traces the visible box (M-7), never an invisible overlap. */
.amc-drag{display:inline-flex;align-items:center;justify-content:center;flex:none;width:44px;height:44px;min-height:44px;padding:0;border:0;background:transparent;color:var(--text-muted);cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none;}
.amc-drag__grip{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border:1px solid var(--chip-border);border-radius:6px;background:var(--surface);font-size:11px;line-height:1;letter-spacing:-2px;transition:background-color var(--motion-press) var(--ease),border-color var(--motion-press) var(--ease),color var(--motion-press) var(--ease),transform var(--motion-press) var(--ease),box-shadow var(--motion-press) var(--ease);}
.amc-drag:hover .amc-drag__grip{border-color:var(--field-border);background:var(--surface-2);color:var(--text);}
.amc-drag:focus-visible{outline:none;}
.amc-drag:focus-visible .amc-drag__grip{outline:2px solid var(--focus);outline-offset:2px;}
.amc-drag:active{cursor:grabbing;}
.amc-drag:active .amc-drag__grip{transform:scale(1.1);box-shadow:var(--shadow-sm);}
.amc-drag--disabled{opacity:.4;cursor:default;touch-action:auto;}
/* P2 desktop data grids are the documented fine-pointer exception. The 44px shared default remains
    authoritative until the desktop/fine-pointer query below opts this surface into the ~24px AA floor. */
.amc-drag--data-grid{width:var(--data-grid-grip-column);height:var(--data-grid-grip-column);min-height:var(--data-grid-grip-column);touch-action:pan-x;}
.amc-drag--data-grid .amc-drag__grip{width:22px;height:22px;}
/* Work-list rows keep a 44px-tall exclusive activator but do not pay a 44px horizontal gutter. The
   narrower button owns only inert left-edge space; it never overlaps the row's selection surface. */
.amc-drag--work-list{width:28px;height:44px;min-height:44px;}
.amc-drag--work-list .amc-drag__grip{width:20px;height:22px;}
/* the lifted row while dragging — elevation + raised stacking; the reflow animation comes from @dnd-kit
   transforms applied via the row's inline style. Used on table rows AND flex cards. */
.amc-dragrow--lifted{position:relative;z-index:5;box-shadow:var(--shadow-pop);background:var(--surface)!important;}
.amc-dragrow--lifted td{background:var(--surface)!important;}
/* while ANY row in a zone is being dragged, soften the others so the drop target reads clearly */
.amc-dragzone.is-dragging .amc-route__row:not(.amc-dragrow--lifted){opacity:.85;}
/* No grip uses negative margins: each surface reserves its whole exclusive button box in normal flow or
   in a fixed divider gutter, so a pointer can never activate the neighbouring row. */

/* --- Service Locations / Route Order: drag + customer/service-location columns (grid template) --- */
.amc-route__col-drag{width:var(--data-grid-grip-column);}
.amc-route__col-customer{width:36%;min-width:120px;}
.amc-route__dragcell{height:44px;padding:0!important;text-align:center;}
.amc-route__customer{min-width:0;}
.amc-route__custname{font-weight:700;color:var(--text);overflow:hidden;text-overflow:ellipsis;display:block;}
.amc-route__custname--none{font-weight:600;color:var(--text-faint);}
/* On a phone the route table scrolls horizontally (the Jobs Config Grid convention) rather than
   reflowing to cards — the few columns (grip · customer · location · jobs) keep a min-width so the
   grip + names stay readable and drag stays reliable. */
@media (max-width:640px){
  .amc-route{min-width:520px;}
  .amc-route__col-customer{min-width:130px;}
}

/* --- Jobs Configuration grid: invariant reserved drag-handle column --- */
.amc-cfg-grid__th-drag{width:var(--data-grid-grip-column);}
.amc-cfg-grid td.amc-cfg-dragcell{height:44px;padding:0;text-align:center;}
.amc-cfg-grid tbody tr.amc-dragrow--lifted td{background:var(--surface)!important;}
.amc-cfg-grid[data-sort-mode="on"] tbody tr{cursor:default;}
.amc-cfg-sorthint{font-size:12px;color:var(--text-muted);margin:0;}
.amc-cfg-sorthint[data-sort-visible="false"]{visibility:hidden;pointer-events:none;}
/* Phase 5.8 r4 — weekday dividers on the grid (mirrors the Route Order page) so a job's weekday is never
   at odds with its rank-derived row position; dragging a row across a divider changes that job's weekday. */
.amc-cfg-grid__group td, .amc-cfg-grid__group th{padding:0;}
.amc-cfg-grid__grouphead{display:table-cell;text-align:left;background:var(--divider-band-surface);font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--divider-band-foreground);padding:0;border-top:1.5px solid var(--border-strong);position:sticky;left:0;}
/* IC-R7 (new owner charter) — the weekday group header sticks while the grid scrolls, mirroring the work list's [data-sort-mode="off"] day band; NOT in Sort, where this row IS the draggable divider. OFR-R5-I: the scroll owner .amc-cfg-gridwrap genuinely scrolls only in the FRAMED shell (inert unframed/phone, exactly as the sticky thead already is).
   OFR-R5-K: Sort-off renders the plain one-line header, which cannot grow. --amc-cfg-grid-sticky-top = MEASURED thead height (JobsGridTable); z-index 1 sits above body cells and below the thead's 2; the pre-existing INERT left:0 (STICKY-FRAMED-001) is untouched. Ledger: docs/history/ic-r7-finding-t-remediation.md. */
.amc-cfg-grid[data-sort-mode="off"] .amc-cfg-grid__grouphead{top:var(--amc-cfg-grid-sticky-top,0px);z-index:1;}
/* A spanning TH remains a table cell. All flex alignment lives inside this wrapper, with a fixed left
   gutter for a divider grip so entering Sort mode cannot change header height or text position. */
.amc-table-divider__inner{position:relative;display:flex;align-items:center;gap:8px;min-height:44px;padding:2px 10px 2px 54px;}
.amc-table-divider__inner>.amc-drag{position:absolute;left:4px;top:50%;transform:translateY(-50%);}
.amc-table-divider__inner>.amc-drag,.amc-visitday__head--divider>.amc-drag,.amc-daydivider>.amc-drag{color:var(--divider-band-foreground);}
.amc-table-divider__inner>.amc-drag .amc-drag__grip,.amc-visitday__head--divider>.amc-drag .amc-drag__grip,.amc-daydivider>.amc-drag .amc-drag__grip{background:var(--divider-band-surface);border-color:var(--border-strong);}
.amc-cfg-grid__group--divider .amc-table-divider__inner,.amc-route__group--divider .amc-table-divider__inner{cursor:grab;}
@media (min-width:721px) and (pointer:fine){
  :root{--data-grid-grip-column:28px;}
  .amc-table-divider__inner{min-height:32px;padding-left:38px;}
  .amc-cfg-grid td.amc-cfg-dragcell{height:32px;}
}
.amc-cfg-grid__group--divider.amc-dragrow--lifted .amc-cfg-grid__grouphead{box-shadow:inset 0 0 0 2px var(--focus);color:var(--text);}

/* Phase 5.8 r4 — drop anchors. The Route page weekday HEADER is a front drop target (land at the TOP of a
   weekday); the work list shows a per-day "move to this day" strip while dragging. Reserved colours
   untouched — the active target uses the focus/selected accent, not a status colour. */
.amc-route__group.is-droptarget .amc-route__grouphead{box-shadow:inset 0 0 0 2px var(--focus);color:var(--text);}
.amc-cfg-grid__group.is-droptarget .amc-cfg-grid__grouphead{box-shadow:inset 0 0 0 2px var(--focus);color:var(--text);}
.amc-route__dropfront{font-weight:700;color:var(--focus);text-transform:none;letter-spacing:0;}
.amc-route__group--divider.amc-dragrow--lifted .amc-route__grouphead{box-shadow:inset 0 0 0 2px var(--focus);color:var(--text);}
.amc-daydrop{display:flex;align-items:center;gap:4px;margin:0 0 6px;padding:8px 12px;min-height:40px;border:1.5px dashed var(--field-border);border-radius:var(--radius);background:var(--surface-2);color:var(--text-muted);font-size:12px;font-weight:600;}
.amc-daydrop.is-droptarget{border-style:solid;border-color:var(--focus);box-shadow:inset 0 0 0 1px var(--focus);color:var(--text);background:var(--surface);}

/* --- Operations / Mark Complete: a left grip handle wraps each open card in Sort mode --- */
/* The sortable wrapper carries the row separator (the inner .amc-jobrow loses its own top border) so
   the dense list still reads as separated rows; the grip sits at the left, the card flexes to fill. */
.amc-jobrow-sortable{display:flex;align-items:stretch;gap:2px;border-top:1px solid var(--divider);}
.amc-joblist > .amc-jobrow-sortable:first-child{border-top:none;}
.amc-jobrow-sortable > .amc-jobrow{border-top:none;flex:1;min-width:0;}
/* N8 audit (OFR-R5-RAILS-SEAM): these --lifted rules do NOT delete the row seam, and must not be
   "fixed" by adding var(--seam). They match the WRAPPER (.amc-jobrow-sortable) or a <tr>/.amc-route__row,
   never a .amc-jobrow — and --seam is defined ON .amc-jobrow, so var(--seam) here would be
   invalid-at-computed-value-time and would blank the whole declaration, destroying --shadow-pop.
   This particular rule additionally has no shipped subject: the work list applies
   amc-dragrow--placeholder (WeeklyWorkList.tsx), never --lifted. Kept, not deleted, because it is
   the correct value if a lifted work-list wrapper is ever reintroduced. */
.amc-jobrow-sortable.amc-dragrow--lifted{box-shadow:var(--shadow-pop);position:relative;z-index:5;border-radius:var(--radius);background:var(--surface);}
.amc-jobrow__drag{align-self:center;margin:0;}
/* OFR-R5-A — a NON-draggable sort row still occupies the grip column so the list keeps ONE left edge.
   Deliberately NOT .amc-jobrow__drag: several specs take .amc-jobrow__drag .first() and assert it is a
   visible, focusable, touch-action:none handle, and a hidden spacer matching that selector would resolve
   first and break them. (GhostVisitRow's older spacer does carry .amc-jobrow__drag; do not harmonise it.) */
.amc-jobrow__nogrip{align-self:center;margin:0;visibility:hidden;}
/* the lifted card is opaque so its elevation reads — beats the higher-specificity highlight tint */
.amc-jobrow-sortable.amc-dragrow--lifted .amc-jobrow{background:var(--surface)!important;}
/* Draggable day-boundary divider (a thin grip strip at the top of a day's list, manager/owner, sort mode) */
.amc-daydivider{display:flex;align-items:center;gap:6px;padding:4px 8px;border-top:1px dashed var(--field-border);background:var(--divider-band-surface);color:var(--divider-band-foreground);font-size:11px;font-weight:600;letter-spacing:.02em;cursor:grab;}
.amc-joblist > .amc-daydivider:first-child{border-top:none;}
.amc-daydivider.amc-dragrow--lifted{box-shadow:var(--shadow-pop);position:relative;z-index:5;border-radius:var(--radius);background:var(--surface);color:var(--text);}
/* Single-zone work-list drag (Phase 10.7): the floating DragOverlay carries the card, so the in-place
   SOURCE row dims to a placeholder — a clear "this is being moved" gap the cross-day reflow animates around. */
.amc-jobrow-sortable.amc-dragrow--placeholder, .amc-daydivider.amc-dragrow--placeholder{opacity:.4;}
.amc-jobrow-sortable.amc-dragrow--placeholder .amc-jobrow{outline:2px dashed var(--field-border);outline-offset:-2px;border-radius:var(--radius);}
/* The floating drag clone painted above EVERYTHING by DragOverlay. A family renders as a compact stack;
   every source row becomes a placeholder at the same time, making the full write scope visible pre-drop. */
.amc-dragfamily{display:flex;flex-direction:column;align-items:stretch;gap:4px;max-width:min(80vw,420px);cursor:grabbing;}
.amc-dragfamily--group{filter:drop-shadow(0 8px 14px rgb(0 0 0 / .14));}
.amc-dragchip{display:flex;align-items:center;gap:8px;max-width:min(80vw,420px);padding:8px 12px;border:1px solid var(--border-strong);border-radius:var(--radius);background:var(--surface);box-shadow:var(--shadow-pop);cursor:grabbing;font-size:13px;}
.amc-dragfamily--group .amc-dragchip{box-shadow:var(--shadow-sm);}
.amc-dragchip--following{margin-left:16px;border-left:3px solid var(--focus);}
.amc-dragchip__grip{flex:none;color:var(--text-muted);font-size:16px;line-height:1;}
.amc-dragchip__body{display:flex;flex-direction:column;min-width:0;}
.amc-dragchip__role{font-size:10px;font-weight:800;line-height:1.2;letter-spacing:.04em;text-transform:uppercase;color:var(--focus);}
.amc-dragchip__name{font-weight:700;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.amc-dragchip__addr{font-size:11px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.amc-dragchip--divider{font-weight:700;color:var(--text);text-transform:uppercase;letter-spacing:.03em;font-size:11px;}
/* The day header doubles as a drop anchor (drop a job here → front of that day / a day of all-completed rows). */
.amc-visitday__head.is-droptarget{box-shadow:inset 0 0 0 2px var(--focus);border-radius:var(--radius);color:var(--text);}
.amc-visitday__dropfront{font-weight:700;color:var(--focus);}

/* --- SORT-003 (owner 2026-07-20, width ladder 2026-07-29): Work-list phone Sort is a focused 44–48px
   planning row. The byte-identical phone baseline below is progressively enriched by width-only tiers;
   grip geometry remains surface-owned. --- */
.amc-jobrow--compact .amc-jobrow__foot,
.amc-jobrow--compact .amc-jobrow__reorder,
.amc-jobrow--compact .amc-jobrow__notes,
.amc-jobrow--compact .amc-jobrow__notepreview,
.amc-jobrow--compact .amc-jobrow__status,
.amc-jobrow--compact .amc-jobrow__details,
.amc-jobrow--compact .amc-jobrow__moveday{display:none;}
/* OFR-R5-A — align-self:stretch here is DEFENCE IN DEPTH, and the honest label matters more than the value.
   It replaced align-self:center, authored (c39f127) for the .amc-jobrow-sortable ROW-flex wrapper (cross
   axis VERTICAL, where center merely centred the fixed 46px row) but reinterpreted as a HORIZONTAL-SIZING
   declaration on the path where a sort row rendered as a DIRECT child of the COLUMN-flex .amc-joblist —
   there it made the whole row box shrink-wrap to its content and self-centre in the list.
   As of this change that bare path is EXTINCT: WeeklyWorkList wraps EVERY sort row in .amc-jobrow-sortable
   (SortableVisitRow when draggable, an inert-grip div otherwise, GhostVisitRow for ghosts), so a sort row's
   cross size is always definite at 46px and align-self is INERT on every shipped path. Reverting this to
   center would not change any page the app renders today, and the rendered gate would NOT catch it — so do
   not describe this declaration as rendered-proven. The WRAPPER is the real, live-measured enforcement of
   the row-box law (tests/ui/sort-left-alignment.spec.ts, injection C1); this declaration is proven only
   against that spec's SYNTHETIC display:contents injection (C2). Keep it: it is the correct value in both
   contexts and the only protection if a future change reintroduces a direct-child sort row. Never restore a
   non-stretch value.
   flex:none stays — in a column list it correctly governs the vertical MAIN axis (no grow/shrink of the 46px
   row), and inside the wrapper .amc-jobrow-sortable > .amc-jobrow{flex:1} already out-specifies it. */
.amc-jobrow--sort{align-self:stretch;flex:none;height:46px;min-height:46px;max-height:46px;overflow:hidden;}
/* N8: its (0,3,0) specificity is PRESERVED and is now correct rather than destructive — it wins the
   SELECT slot only. As a box-shadow declaration it erased the flag rail (but retained var(--seam)), so a
   checked carry row in sort mode lost its carry rail. */
.amc-jobrow.amc-jobrow--sort.is-checked{--rail-select:inset 3px 0 0 var(--positive);}
.amc-jobrow__swipe--sort .amc-jobrow__swipetrack{width:100%;transform:none!important;touch-action:auto;}
.amc-jobrow--sort .amc-jobrow__main{align-items:center;height:46px;min-height:46px;padding:4px 6px;cursor:default;touch-action:auto;user-select:text;-webkit-user-select:text;overflow:hidden;}
.amc-jobrow--sort .amc-jobrow__text{height:100%;justify-content:center;gap:0;min-width:0;overflow:hidden;}
.amc-jobrow--sort .amc-jobrow__descwrap{display:none;}
.amc-jobrow--sort .amc-jobrow__descfull,
.amc-jobrow--sort .amc-jobrow__donedate{display:none;}
.amc-jobrow--sort .amc-jobrow__line1{width:100%;min-width:0;flex-wrap:nowrap;overflow:hidden;}
.amc-jobrow--sort .amc-jobrow__id{flex:1 1 auto;width:100%;flex-wrap:nowrap;min-width:0;overflow:hidden;white-space:nowrap;line-height:1.2;}
/* WORKFIT-001 — CONTENT-SIZED, never constant-sized: flex-basis auto with grow 0, so a row shows all that
   fits, truncates only on a real deficit, and leaves surplus at the END rather than inflating a short item's
   box. Shrink WEIGHTS run SORT-003's spend order backwards, so the name yields before the stop label and the
   label before the address. NEVER reintroduce a ch basis, a percentage max-width, or a width tier: a
   constant cannot know what a row holds. Law + gate: docs/architecture/work-list-gesture-laws.md. */
.amc-jobrow--sort .amc-jobrow__name{flex:0 400 auto;min-width:3ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.amc-jobrow--sort .amc-jobrow__addrline{flex:0 1 auto;min-width:0;overflow:hidden;white-space:nowrap;}
.amc-jobrow--sort .amc-jobrow__glyph,
.amc-jobrow--sort .amc-flagbadge{flex:none;}
.amc-jobrow--sort .amc-labelbadge{flex:0 20 auto;min-width:3ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.amc-jobrow--compact .amc-jobrow__addr{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}
.amc-jobrow--sort.amc-jobrow--done{align-items:center;}
/* OFR-R5-A — justify-content is DELIBERATELY absent here. The rule that WAS here declared
   justify-content:center; this 3-class selector (0,3,0) out-specifies the 721px tier's 2-class
   .amc-jobrow--sort .amc-jobrow__text{...justify-content:flex-start} (0,2,0 — a media query adds no
   specificity), so that deleted declaration kept COMPLETED sort rows horizontally centred above 721px. Its
   deletion is load-bearing and is negative-controlled by injection B in
   tests/ui/sort-left-alignment.spec.ts, which puts the exact rule back and requires the gate to go red.
   Declaring nothing lets ONE rule govern each axis: below 721px the row inherits
   justify-content:center from .amc-jobrow--sort .amc-jobrow__text (column axis → the intended VERTICAL
   centring of the fixed 46px row) and at/above 721px it inherits flex-start from the tier rule. Any future
   higher-specificity re-declaration of justify-content (or align-self) on a sort row's text container
   re-opens OFR-R5-A and must restate the law inside the width tier. */
.amc-jobrow--sort.amc-jobrow--done .amc-jobrow__text{height:46px;padding:4px 6px;overflow:hidden;}
.amc-jobrow--sort.amc-jobrow--stacked{padding-left:10px;}
.amc-jobrow--sort.amc-jobrow--stacked::before{left:3px;}

/* SORT-003 REVEAL ladder — what a sort row SHOWS, never how wide anything is (WORKFIT-001). Four UNCLIP
   tiers that lived here (721 address, 760 stop label, 800 name, 1280 zone) are DELETED, not moved: a media
   query sees neither a row's content nor its container, which is why a 17-character label and a 2-character
   one were laid out at the identical 38.0px. Never key a tier to pointer type — an 844px landscape phone
   earns a narrow desktop's context. What survives is discrete (does a preview EXIST). */
@media (min-width:721px){
  /* OFR-R5-A — justify-content MUST be restated when the axis flips. The base rule sets
     justify-content:center for a COLUMN container (vertical centring in the fixed 46px row); flipping
     to row silently reinterprets that same declaration as HORIZONTAL centring, which is what centred
     the rows. align-items now owns the vertical axis. */
  .amc-jobrow--sort .amc-jobrow__text{flex-direction:row;align-items:center;justify-content:flex-start;gap:10px;}
  .amc-jobrow--sort .amc-jobrow__line1{flex:0 1 auto;width:auto;}
  .amc-jobrow--sort .amc-jobrow__id{flex:0 1 auto;width:auto;}
}
@media (min-width:840px){
  /* Surplus is spent on the instruction preview LAST, so it gives room back FIRST (SORT-003 order) —
     hence the largest shrink weight on the row; basis auto stops it inflating past its own text. */
  .amc-jobrow--sort .amc-jobrow__descwrap{display:block;flex:0 8000 auto;min-width:8ch;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
  .amc-jobrow--sort .amc-jobrow__sortdesc{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;color:var(--text-muted);}
  .amc-jobrow--sort .amc-jobrow__donedate{display:block;flex:none;margin:0;white-space:nowrap;}
}
@media (min-width:960px){
  .amc-jobrow--sort .amc-jobrow__zonechip{display:inline-flex;flex:0 20 auto;min-width:3ch;overflow:hidden;text-overflow:ellipsis;}
}
/* The assignee cap below is KEPT and is NOT the WORKFIT-001 defect class: these chips are ALL-OR-NOTHING and
   AssignmentChips.tsx:24 compares scrollWidth to clientWidth to hide the set, so 22ch IS that fit test, not
   a truncation policy — remove it and a long set overflows, then hides itself, leaving the gap it avoids. */
@media (min-width:1120px){
  .amc-jobrow--sort .amc-jobrow__assignees{display:flex;flex:none;flex-wrap:nowrap;max-width:22ch;margin:0;overflow:hidden;}
  .amc-jobrow--sort .amc-jobrow__assignees[data-all-or-nothing="yes"][data-fit="no"]{visibility:hidden;}
}
@media (min-width:1440px){
  .amc-jobrow--sort .amc-jobrow__assignees{max-width:none;overflow:visible;}
}

/* --- Owner round 3: highlight tints the WHOLE row (not a swatch box). Only OPEN, un-checked rows are
   tinted — the reserved semantic states win (green = done, Citrus = checked) so the highlight never
   obscures status (jobs-read-model-and-lifecycle.md highlight rule). color-mix → a soft tint. --- */
.amc-jobrow:not(.is-checked):not(.amc-jobrow--done)[data-hl="yellow"]{background:color-mix(in srgb, var(--hl-yellow) 26%, var(--surface));}
.amc-jobrow:not(.is-checked):not(.amc-jobrow--done)[data-hl="pink"]{background:color-mix(in srgb, var(--hl-pink) 26%, var(--surface));}
.amc-jobrow:not(.is-checked):not(.amc-jobrow--done)[data-hl="blue"]{background:color-mix(in srgb, var(--hl-blue) 26%, var(--surface));}
.amc-jobrow:not(.is-checked):not(.amc-jobrow--done)[data-hl="purple"]{background:color-mix(in srgb, var(--hl-purple) 26%, var(--surface));}
.amc-jobrow:not(.is-checked):not(.amc-jobrow--done)[data-hl="cyan"]{background:color-mix(in srgb, var(--hl-cyan) 26%, var(--surface));}

/* --- Normal-lens row rhythm: compact, full-width auxiliary actions (named 28px height exception). --- */
/* OFR-R5-B — 28→24px. Keeps flex:1 1 0 full-width distribution (owner ruling 2026-07-29) and stays
   under 44px per the owner's named density exception: the vertical space is reclaimed for more rows. */
.amc-jobrow__act{display:inline-flex;flex:1 1 0;align-items:center;justify-content:center;min-width:30px;height:24px;padding:0 6px;border:none;background:none;color:var(--text-muted);font-size:15px;line-height:1;cursor:pointer;border-radius:6px;}
.amc-jobrow__act:hover{background:var(--chip-surface);color:var(--text);}
.amc-jobrow__act:focus-visible{outline:2px solid var(--focus);outline-offset:-1px;}
.amc-jobrow__actn{font-size:11px;font-weight:700;margin-left:1px;vertical-align:super;}
/* POLISH-ICONS-001 — a fixed 17px box (font-size:15px sized the old emoji, not an SVG), plus the
   open-state this sheet never had (0 aria-expanded rules; :hover never fires on touch). Owner ruling
   2026-08-19: SELECTED FILL + KEYLINE; path data stays byte-identical. See docs/decisions/action-icon-system-2026-08-19.md */
.amc-jobrow__act svg{width:17px;height:17px;flex:none;}
.amc-jobrow__act[aria-expanded="true"]{background:var(--selected-surface);color:var(--text);box-shadow:inset 0 0 0 1px var(--positive-border);}
.amc-swipeaction svg{width:20px;height:20px;flex:none;}

/* --- Phase 6A: operational flags (whole-row tint, wins over the job highlight). Orange = missed-work
   carry-forward (👁 "Missed from week of M/D"); red = QC rework (🚨). A left accent bar + a pill badge
   keep the state legible on a dense list. Reserved colours per jobs-read-model-and-lifecycle.md. --- */
.amc-jobrow:not(.is-checked):not(.amc-jobrow--done)[data-flag="carry_forward"]{background:color-mix(in srgb, var(--flag-carry) 20%, var(--surface));}
.amc-jobrow:not(.is-checked):not(.amc-jobrow--done)[data-flag="rework"]{background:color-mix(in srgb, var(--flag-rework) 18%, var(--surface));}
/* N8 — the operational flag owns the 6px OUTER rail slot. Its inner 3px is overpainted when a selection
   or future rail is present, leaving a 3-6px band, so a checked carry row shows BOTH cues at once (that
   pairing previously rendered one rail only). Solo, the flag reads as a full 0-6px bar.
   DF-009 WIDTH RETIREMENT (owner-eyeball item): rework was a 4px bar and carry 3px, "so the truer red
   reads as urgent at a glance". Both now sit in the same 6px slot, so that relative-width distinction is
   RETIRED. It was never a side-by-side discriminator — a row has exactly one data-flag, so the two bars
   never appear together — and the truer red (--flag-rework #D11A1A vs --flag-carry #E8730C) plus the
   🚨/👁 badge still carry the urgency. Going wider is not available: 6px is capped by
   .amc-jobrow--sort .amc-jobrow__main's 6px padding-left below, and widening THAT padding would break
   the sort left-alignment law (tests/ui/sort-left-alignment.spec.ts, ALIGNMENT_TOLERANCE_PX = 1). */
.amc-jobrow[data-flag="carry_forward"]{--rail-flag:inset 6px 0 0 var(--flag-carry);}
.amc-jobrow[data-flag="rework"]{--rail-flag:inset 6px 0 0 var(--flag-rework);}
.amc-flagbadge{display:inline-flex;align-items:center;gap:3px;font-size:10px;font-weight:800;letter-spacing:.02em;padding:1px 6px;border-radius:999px;margin-right:6px;text-transform:uppercase;white-space:nowrap;}
.amc-flagbadge--carry{background:color-mix(in srgb, var(--flag-carry) 16%, var(--surface));color:var(--flag-carry);}
.amc-flagbadge--rework{background:color-mix(in srgb, var(--flag-rework) 14%, var(--surface));color:var(--flag-rework);}
/* WORKLIST-002 — the carry rail + badge already own provenance. The structural priority cue therefore
   enhances the EXISTING real-day label instead of adding a third marker or a fourth rail. The 6px rail
   budget is exhausted (N8); this dedicated non-rail tint slot cannot collide with selection/future/flag. */
.amc-jobrow[data-projection="missed"]{--cue-missed-projection:color-mix(in srgb, var(--flag-carry) 10%, var(--surface));}
.amc-jobrow__prioritydate{display:inline-flex;align-items:center;white-space:nowrap;font-size:11px;font-weight:750;color:var(--text);background:var(--cue-missed-projection, transparent);border:1px solid color-mix(in srgb, var(--flag-carry) 32%, transparent);border-radius:999px;padding:1px 6px;margin-right:6px;}
.amc-jobrow__qcfail{color:var(--flag-rework);font-weight:700;}

/* --- Phase 6B: manager dismiss action + "missed to top" setting toggle + QC review dashboard. --- */
.amc-jobrow__dismiss:hover{color:var(--destructive);background:var(--destructive-surface);}
.amc-mcset{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600;color:var(--text-muted);cursor:pointer;white-space:nowrap;}
.amc-mcset input{width:16px;height:16px;}
.amc-qcr-stats{display:flex;flex-wrap:wrap;gap:10px;margin:6px 0 14px;}
.amc-qcr-stat{display:flex;flex-direction:column;align-items:center;min-width:84px;padding:10px 14px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);}
.amc-qcr-stat__n{font-size:22px;font-weight:800;color:var(--text);line-height:1;}
.amc-qcr-stat__l{font-size:11px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.03em;margin-top:4px;}
.amc-qcr-sec{margin:0 0 16px;}
.amc-qcr-sec__h{font-size:14px;margin:0 0 8px;display:flex;align-items:center;gap:6px;}
.amc-qcr-sec__h[data-flag="rework"]{color:var(--flag-rework);}
.amc-qcr-sec__h[data-flag="carry_forward"]{color:var(--flag-carry);}
.amc-qcr-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px;}
.amc-qcr-row{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;padding:8px 10px;border-top:1px solid var(--divider);background:var(--surface);}
.amc-qcr-row:first-child{border-top:none;}
.amc-qcr-row[data-flag="rework"]{box-shadow:inset 3px 0 0 var(--flag-rework);}
.amc-qcr-row[data-flag="carry_forward"]{box-shadow:inset 3px 0 0 var(--flag-carry);}
.amc-qcr-row--done{opacity:.6;}
/* HIERARCHY-002 — a Property card owning its Stops. The group row stacks (address, rollup, stops)
   instead of the flat baseline row, and the nested stop list is indented + rail-marked so the two
   hierarchy levels read as parent and child rather than as one flat list. */
.amc-qcr-row--group{flex-direction:column;align-items:stretch;gap:4px;}
.amc-qcr-list--nested{margin-top:4px;padding-left:12px;border-left:2px solid var(--divider);}
.amc-qcr-list--nested .amc-qcr-row{background:transparent;padding:6px 0;}
.amc-qcr-row__name{font-weight:700;color:var(--text);}
.amc-qcr-row__meta{font-size:12px;color:var(--text-muted);}
/* Mobile layout-viewport ownership (KBINSET-001 sibling sweep, 2026-09-02). Identical mechanism to
   dd.amc-mono, on the same service-location page: ContactPicker falls back to a raw crmContactId as the
   row NAME and the legacy-conflict rows quote contact ids, all inside a flex-wrap row whose items would
   otherwise be floored at their min-content width. .amc-mono covers the inline spans; these two classes
   also render bare identifiers, so they own the rule themselves.
   SEPARATE rules on purpose: test/unit/list-skeleton-css.test.ts pins the two declarations above verbatim,
   because the QC list-skeleton's 86px row constant was MEASURED against them and goes stale if the row's
   padding/borders/gaps/type move. Neither declaration added here is one of those - a break opportunity and
   a flex min-size floor change nothing about a row of ordinary prose - so the pin stays intact and keeps
   guarding what it was written to guard. */
.amc-qcr-row>*{min-width:0;}
.amc-qcr-row__name,.amc-qcr-row__meta{overflow-wrap:anywhere;}

/* --- Phase 6C: crew time tracking controls + visit/job drill-down pages. --- */
.amc-timetrack{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;padding:8px 10px;margin:2px 0 6px;border-top:1px dashed var(--divider);font-size:13px;}
.amc-timetrack[data-running="yes"]{background:color-mix(in srgb, var(--positive) 8%, var(--surface));}
.amc-timetrack__totals{display:flex;align-items:center;gap:10px;}
.amc-timetrack__clock{font-weight:800;font-variant-numeric:tabular-nums;}
.amc-timetrack__mh{color:var(--text-muted);font-weight:700;}
.amc-timetrack__live{color:var(--positive);font-weight:700;font-size:12px;}
.amc-timetrack__ctrls{display:flex;align-items:center;gap:8px;}
.amc-timetrack__crew{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--text-muted);}
.amc-timetrack__crew input{width:48px;height:32px;text-align:center;border:1px solid var(--field-border);border-radius:8px;}
.amc-timetrack__switch{color:var(--focus);}
.amc-timetrack__err{color:var(--destructive);font-size:12px;width:100%;}
/* TIME-002 — the billing timesheet (man-hours prominent + per-segment edit rows). */
.amc-timesheet{font-size:13px;}
.amc-timesheet__total{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 8px;padding:8px 0 10px;}
.amc-timesheet__mh{font-size:26px;font-weight:800;font-variant-numeric:tabular-nums;color:var(--text);}
.amc-timesheet__mhlabel{font-size:13px;font-weight:700;color:var(--text-muted);}
.amc-timesheet__clock{font-size:12px;margin-left:auto;}
.amc-timesheet__empty{font-size:13px;}
.amc-timesheet__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px;}
.amc-timesheet__row{display:flex;align-items:center;flex-wrap:wrap;gap:6px 12px;padding:7px 8px;border-top:1px solid var(--divider);}
.amc-timesheet__row:first-child{border-top:none;}
.amc-timesheet__row--edit{align-items:flex-end;background:var(--surface-2);border-radius:8px;}
.amc-timesheet__when{font-variant-numeric:tabular-nums;}
.amc-timesheet__crew{color:var(--text-muted);}
.amc-timesheet__rowmh{font-weight:700;font-variant-numeric:tabular-nums;}
.amc-timesheet__rowacts{display:inline-flex;align-items:center;gap:6px;margin-left:auto;}
.amc-timesheet__del{color:var(--destructive);}
.amc-timesheet__fields{display:flex;flex-wrap:wrap;gap:8px 12px;flex:1;min-width:0;}
.amc-timesheet__field{display:flex;flex-direction:column;gap:2px;font-size:11px;color:var(--text-muted);}
.amc-timesheet__field input{height:34px;}
.amc-timesheet__field--crew input{width:64px;text-align:center;}
.amc-timesheet__add{margin-top:8px;}
.amc-timesheet__err{color:var(--destructive);font-size:12px;margin-top:6px;}
.amc-detail-page{max-width:760px;}
.amc-detail-sec{margin:0 0 16px;}
.amc-detail-sec__h{font-size:13px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-muted);margin:0 0 8px;border-bottom:1px solid var(--divider);padding-bottom:4px;}
.amc-detail-sec__h--toggle{padding-bottom:0;}
.amc-detail-sec__toggle{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;min-height:44px;padding:4px 2px;border:0;background:none;color:inherit;font:inherit;font-weight:700;text-transform:inherit;letter-spacing:inherit;cursor:pointer;text-align:left;}
.amc-detail-sec__toggle:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.amc-detail-sec__content{padding-top:1px;}
.amc-detail-grid,.amc-summary-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px 14px;margin:0;}
.amc-detail-grid dt,.amc-summary-grid dt{font-size:11px;text-transform:uppercase;letter-spacing:.02em;color:var(--text-faint);}
.amc-detail-grid dd,.amc-summary-grid dd{margin:0;font-weight:600;color:var(--text);overflow-wrap:anywhere;}
.amc-detail-highlight{display:flex;align-items:center;gap:6px;}
.amc-detail-fieldactions{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px;}

/* --- EDITSURFACE-001: the shared page-level edit mode (DF-020 as locked). One pencil flips the
   page's fields to inputs IN PLACE — same grid, same order, same position — and a sticky bar owns
   Save/Cancel. Phone-first: the bar never scrolls away and both controls clear 44px. --- */
.amc-pageedit__grid{align-items:start;}
.amc-pageedit__field{display:flex;flex-direction:column;gap:4px;min-width:0;}
.amc-pageedit__label{font-size:11px;text-transform:uppercase;letter-spacing:.02em;color:var(--text-faint);}
.amc-pageedit__readvalue{font-weight:600;color:var(--text);overflow-wrap:anywhere;}
.amc-pageedit__field.is-readonly{opacity:.85;}
.amc-pageedit__help{font-size:12px;}
.amc-pageedit__boundary{display:block;font-size:12px;font-weight:400;margin-top:2px;}
.amc-pageedit__toggle{display:flex;align-items:center;gap:8px;min-height:44px;font-weight:600;}
.amc-pageedit__richtext{min-height:88px;}
.amc-pageedit__bar{position:sticky;bottom:0;z-index:5;display:flex;flex-direction:column;gap:8px;margin:12px 0 0;padding:10px 12px calc(10px + env(safe-area-inset-bottom));background:var(--surface);border-top:1px solid var(--divider);box-shadow:0 -6px 18px rgba(0,0,0,.10);}
.amc-pageedit__baractions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;}
.amc-pageedit__baractions .amc-btn{min-height:44px;flex:1 1 auto;}
.amc-pageedit__error{margin:0;}
.amc-pageedit__sec{margin:0 0 16px;}
.amc-pageedit__reverts{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;}
@media (min-width:560px){.amc-pageedit__baractions .amc-btn{flex:0 0 auto;min-width:120px;}}

/* --- Phase 6A: QC fail / create-rework dialog (bottom sheet; reuses .amc-sheet + .amc-field). --- */
.amc-qcsheet__title{margin:0 0 4px;font-size:16px;}
.amc-qcsheet__subtitle{margin:0 0 10px;font-size:13px;}
.amc-qcsheet__row{display:block;margin:10px 0;}
.amc-qcsheet__label{display:block;font-weight:700;font-size:13px;margin-bottom:4px;}
.amc-qcsheet__note,.amc-qcsheet__date{width:100%;}
.amc-qcsheet__hint{display:block;margin-top:4px;font-size:12px;}
.amc-qcsheet__actions{display:flex;gap:8px;margin-top:14px;}
/* DF-019 — the reschedule dialog's route-position door sits above the actions with its explainer. */
.amc-schededit__routemove{display:flex;align-items:center;gap:8px;margin:12px 0 0;font-size:12.5px;}
/* ASSIGN-001 — the visit drill-down assignment row: chips + explicit override/inherited source tag. */
.amc-assignsec{display:flex;align-items:center;flex-wrap:wrap;gap:8px;}
.amc-assignsec__source{font-size:12px;color:var(--text-muted);}
.amc-assignsec__source.is-override{color:var(--text);font-weight:700;}

/* --- Owner round 3: a fixed Sort toggle on the work list that follows the viewport (start sorting
   without scrolling back to the top). --- */
.amc-sortfab{position:fixed;bottom:calc(20px + env(safe-area-inset-bottom));right:14px;z-index:25;display:inline-flex;align-items:center;gap:6px;min-height:40px;padding:8px 14px;border:1px solid var(--chip-border);border-radius:999px;background:var(--surface);color:var(--text);font-size:13px;font-weight:700;cursor:pointer;box-shadow:0 6px 18px -8px rgba(0,0,0,.45);}
.amc-sortfab:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.amc-sortfab.is-on{background:var(--primary);color:#fff;border-color:var(--primary);}
/* DF-001 — distinct, non-reserved colour per sort state: Visits = primary (dark); Jobs = a clear blue,
   away from the reserved green(done)/red-fuchsia(QC)/orange(carry-forward)/citrus(selected). */
.amc-sortfab--jobs.is-on{background:#2563A8;color:#fff;border-color:#2563A8;}
.amc-sortmode__switch{font-weight:700;}
/* DF-005 — when a draft is checked the submit bar (.amc-stickybar, z-30) owns the bottom, so raise the
   FAB above it (and over it) so the sole sort toggle stays reachable on a phone. */
.amc-sortfab[data-raised="yes"]{bottom:calc(118px + env(safe-area-inset-bottom));z-index:31;}
/* DF-015e — the row-density FAB: a bottom-LEFT sibling to the bottom-right sort FAB (expand/collapse all
   rows). Left, not the spec's centre, so it doesn't stack on the centred toast + submit bar. */
.amc-viewfab{position:fixed;bottom:calc(20px + env(safe-area-inset-bottom));left:14px;z-index:25;display:inline-flex;align-items:center;gap:6px;min-height:40px;padding:8px 14px;border:1px solid var(--chip-border);border-radius:999px;background:var(--surface);color:var(--text);font-size:13px;font-weight:700;cursor:pointer;box-shadow:0 6px 18px -8px rgba(0,0,0,.45);}
.amc-viewfab:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.amc-viewfab.is-on{background:var(--primary);color:#fff;border-color:var(--primary);}
.amc-viewfab[data-raised="yes"]{bottom:calc(118px + env(safe-area-inset-bottom));z-index:31;}
/* CREATE-001 — the owner-specified bottom-CENTRE Create Job entry on the work list (manager/owner
   only; React hides it while a checked draft's stickybar owns the centre slot). Primary-filled pill
   between the corner FABs; >=44px target; a real link so browser affordances work. */
.amc-createfab{position:fixed;bottom:calc(20px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);z-index:24;display:inline-flex;align-items:center;gap:6px;min-height:44px;min-width:44px;justify-content:center;padding:10px 16px;border:1px solid var(--primary);border-radius:999px;background:var(--primary);color:#fff;font-size:13px;font-weight:700;text-decoration:none;cursor:pointer;box-shadow:0 6px 18px -8px rgba(0,0,0,.45);}
.amc-createfab:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.amc-createfab:hover{filter:brightness(1.06);}
/* Codex correction 4 — narrow phones: the corner FABs and the centre pill must each keep an
   EXCLUSIVE usable target at 320px, so the pill goes icon-only (its aria-label still names it). */
@media (max-width:420px){
  .amc-createfab{padding:10px 13px;}
  .amc-createfab__text{display:none;}
}

/* PR 75 — the Jobs-sort kebab (⋮): stacked just ABOVE the sort FAB on the right (matches its raised offset
   above a checked draft). Pops a small menu upward (toggle ghosts + make this week's order permanent). */
.amc-sortkebab-wrap{position:fixed;right:14px;bottom:calc(70px + env(safe-area-inset-bottom));z-index:26;}
.amc-sortkebab-wrap[data-raised="yes"]{bottom:calc(168px + env(safe-area-inset-bottom));z-index:32;}
/* R5-V-FAB-PADDING — THE BOTTOM-FIXED CONTROL BAND, published once for every surface that has to reserve
   space above it. Derived from the rules directly above as (css bottom constant + rendered height) — how far
   each control reaches up from the viewport bottom. The safe-area term is added once here because every
   offset above already stacks env(safe-area-inset-bottom) on top of its own constant:
     resting  .amc-sortfab / .amc-viewfab 20+40=60 · .amc-createfab 20+44=64 · .amc-sortkebab-wrap 70+44=114
     raised   (a checked draft hands .amc-stickybar the bottom, so DF-005 lifts the rest)
              .amc-stickybar 0+78=78 · .amc-sortfab / .amc-viewfab 118+40=158 · .amc-sortkebab-wrap 168+44=212
   The value is the state's UNION MAX, not the lens's: the Jobs-only kebab sets both numbers so a lens
   transition can never momentarily un-reserve the band it is about to need. Move a constant above and this
   must move with it. MarkCompleteApp stamps data-fab-band="raised" from the SAME expression that renders
   CompletionDraftBar and sets every data-raised, so the two can't drift apart.
   KNOWN SIBLING, deliberately not consumed here: .amc-mcpage's own 128px page-bottom padding is the
   list-level instance of this same reservation. It predates this variable, omits env(safe-area-inset-bottom),
   and under-reserves the raised band by 84px. Left byte-identical by this chunk and reported, not silently
   preserved — converting it moves every list's resting geometry and belongs in its own change.
   KNOWN SIBLING, disclosed but not covered: .amc-toast is fixed at bottom:22px inside .amc-mcpage and can be
   raised by FilterPanel's own refusal path. Long measured messages reach 128-130px versus the 114px resting
   reserve; because the toast is centered, an intersection-only oracle can miss it while the structural band
   assertion catches it. The toast is transient by design, so this chunk records rather than reserves it. */
.amc-mcpage{--amc-fab-reserve:calc(114px + env(safe-area-inset-bottom));}
.amc-mcpage[data-fab-band="raised"]{--amc-fab-reserve:calc(212px + env(safe-area-inset-bottom));}
.amc-sortkebab{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border:1px solid var(--chip-border);border-radius:999px;background:var(--surface);color:var(--text);font-size:20px;line-height:1;font-weight:700;cursor:pointer;box-shadow:0 6px 18px -8px rgba(0,0,0,.45);}
.amc-sortkebab:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.amc-sortkebab__scrim{position:fixed;inset:0;z-index:0;background:transparent;border:0;padding:0;cursor:default;}
.amc-sortkebab__menu{position:absolute;right:0;bottom:calc(100% + 8px);z-index:1;min-width:252px;display:flex;flex-direction:column;padding:6px;border:1px solid var(--border-strong);border-radius:var(--radius);background:var(--surface);box-shadow:var(--shadow-pop);}
.amc-sortkebab__item{display:flex;align-items:center;gap:6px;width:100%;text-align:left;padding:10px;min-height:44px;border:0;border-radius:8px;background:transparent;color:var(--text);font-size:14px;cursor:pointer;}
.amc-sortkebab__item:hover{background:var(--surface-2);}
.amc-sortkebab__item:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
.amc-sortkebab__item:disabled{color:var(--text-faint);cursor:not-allowed;}
.amc-sortkebab__check{display:inline-block;width:16px;flex:none;color:var(--primary);font-weight:700;}

/* PR 75 — the faded "This Week's Visit" GHOST row (Jobs-sort durable lens): a citrus-dashed, subordinate
   marker showing where a visit sits THIS week vs the durable (solid) slot. Readable but clearly secondary
   (~opacity .6 — the exact fade is an owner interaction-check item). Citrus = the selected/this-week accent. */
.amc-ghostrow{display:flex;align-items:center;gap:6px;margin:2px 0;padding:6px 8px;border:1px dashed var(--selected);border-radius:var(--radius);background:var(--selected-surface);opacity:.6;}
.amc-ghostrow.is-checked{opacity:1;border-style:solid;border-color:var(--positive);}
.amc-ghostrow__nogrip{visibility:hidden;}
.amc-ghostrow__body{display:flex;align-items:flex-start;gap:8px;min-width:0;}
.amc-ghostrow__badge{flex:none;margin-top:1px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text);background:var(--selected-surface);border:1px solid var(--selected);border-radius:999px;padding:2px 7px;}
.amc-ghostrow__id{display:flex;flex-direction:column;min-width:0;gap:1px;}
.amc-ghostrow__name{font-size:13px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
.amc-ghostrow__addr{font-size:11.5px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
.amc-ghostrow__desc{font-size:12px;font-style:italic;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
.amc-ghostrow--sort{min-height:46px;max-height:48px;margin:0;padding:4px 6px;overflow:hidden;}
.amc-ghostrow--sort .amc-ghostrow__body{flex:1;align-items:center;gap:5px;min-width:0;overflow:hidden;}
.amc-ghostrow--sort .amc-ghostrow__badge{margin:0;padding:1px 5px;white-space:nowrap;}
.amc-ghostrow--sort .amc-ghostrow__id{flex:1;flex-direction:row;align-items:baseline;gap:5px;min-width:0;overflow:hidden;white-space:nowrap;}
.amc-ghostrow--sort .amc-ghostrow__name{flex:1 1 12ch;min-width:3ch;font-weight:700;}
.amc-ghostrow--sort .amc-ghostrow__addr{flex:1 1 10ch;max-width:42%;}
.amc-ghostrow--sort .amc-ghostrow__desc{display:none;}
.amc-dragchip--ghost{border-style:dashed;opacity:.9;}

/* Jobs-sort week-override PAIR (owner model 2026-06-30): a job's durable "Future weeks only" SOLID and its
   "This week's visit" GHOST share a neutral slate LEFT ACCENT so they read as ONE job even a few rows apart;
   the two badges carry the roles. (Owner interaction-check: the accent weight + whether to also slate the ghost
   badge — slate chosen as a non-reserved hue so it never collides with done/QC/carry/highlight colours.) */
/* FIXED by OFR-R5-RAILS-SEAM (law N8). The prior note here recorded that this and the carry/rework/
   checked rails were all box-shadow at equal specificity and OVERRODE one another, so a future-flagged
   carry row silently lost its carry rail. That is what the slot ladder removes: the flag keeps the 6px
   outer slot, this takes the 3px INNER slot, and both paint.
   Sharing the inner slot with --rail-select is safe by CONSTRUCTION, not by luck: WeeklyWorkList.tsx
   passes completable={!divergentIds.has(v.id)} and futureWeeksOnly={divergentIds.has(v.id)} — exact
   inverses — while is-checked requires (checked && completable) (VisitCompletionCard.tsx). A row can
   therefore never carry data-future="yes" and is-checked at once. */
.amc-jobrow[data-future="yes"]{--rail-future:inset 3px 0 0 var(--pair-accent);}
/* .amc-ghostrow is NOT a .amc-jobrow (WeeklyWorkList.tsx renders it as .amc-jobrow-sortable.amc-ghostrow),
   so it has no seam and no slots — its box-shadow cannot collide and is left as a direct declaration. Its
   only row separator is .amc-jobrow-sortable's 1px solid var(--divider) hairline, i.e. the same
   low-contrast separator the seam above exists to replace. Reported as an adjacent finding, out of scope
   here; ghost rows are untinted so they are not the reported symptom. */
.amc-ghostrow{box-shadow:inset 3px 0 0 var(--pair-accent);}
.amc-pairbadge--future{background:var(--pair-surface);color:var(--pair-accent);border:1px solid color-mix(in srgb, var(--pair-accent) 32%, transparent);text-transform:none;letter-spacing:.01em;}
/* Merge-drop hint: a small "put back on schedule" affordance the dragged ghost's chip carries so dropping it
   back onto its job (to merge/eliminate the override) is discoverable, not invisible. (A contextual highlight
   of the drop TARGET while hovering is a possible future enhancement — needs live drag-over state plumbing.) */
.amc-dragchip__merge{display:block;margin-top:2px;font-size:10.5px;font-weight:700;color:var(--pair-accent);}

/* Lightweight mode-switch motion (2026-06-30 owner ask): the Jobs-sort "future weeks" ghosts visibly EMERGE
   when you enter the durable lens. Opacity-only (no layout/transform) so it never disturbs the scroll anchor
   that keeps your top-of-viewport row put. @media reduced-motion opts out. */
@keyframes amc-ghost-emerge { from { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) {
  /* fill: none — after the fade the row reverts to its CSS opacity (.6, or 1 when checked), so a later check
     isn't pinned by the animation. */
  .amc-ghostrow { animation: amc-ghost-emerge 200ms ease; }
}

/* PR 75 — a brief centered, lightly-dimmed spinner while a sort-mode re-fetch (durable / week order) lands.
   Starts at the filter bar's rendered BOTTOM EDGE in viewport coordinates (--amc-listcover-top), never at its
   HEIGHT: the two agree only while the bar is pinned at 0, and once R5-V-FAB-PADDING bounded the open bar
   SHORTER than its distance down the page the height started this cover ABOVE the bar — painting over the
   filter control the load had just been committed from. Height fallback for surfaces with no FilterPanel. */
.amc-listspin{position:fixed;inset:var(--amc-listcover-top,var(--amc-day-sticky-top,0px)) 0 0;z-index:40;display:flex;align-items:center;justify-content:center;background:rgba(45,41,38,.12);}
.amc-listspin__card{display:inline-flex;align-items:center;gap:10px;padding:12px 18px;border:1px solid var(--border-strong);border-radius:var(--radius);background:var(--surface);box-shadow:var(--shadow-pop);color:var(--text);font-size:14px;}
.amc-listspin__label{font-weight:600;}

/* PR 75 — the Settings screen's per-location missed-work-sort control (a radio list of 3 options). */
.amc-settings-section__title{margin:0 0 4px;font-size:16px;font-weight:700;}
.amc-settings-section__desc{margin:0;font-size:13px;}
.amc-settings-opts{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;border:0;}
.amc-settings-opts__legend{padding:0;margin:0 0 4px;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);}
.amc-settings-opt{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;border:1px solid var(--border);border-radius:10px;background:var(--surface);cursor:pointer;}
.amc-settings-opt:hover{background:var(--surface-2);}
.amc-settings-opt input{margin-top:3px;min-width:18px;min-height:18px;accent-color:var(--primary);}
.amc-settings-opts:disabled .amc-settings-opt{cursor:default;opacity:.75;}
.amc-settings-opt__text{display:flex;flex-direction:column;gap:1px;}
.amc-settings-opt__label{font-size:14px;font-weight:600;color:var(--text);}
.amc-settings-opt__help{font-size:12px;}
.amc-settings-status{margin:0;font-size:13px;}

/* ===== DESIGN-001 — modern visual refresh (Phase A): motion, elevation, skeletons, breadcrumbs =====
   All additive and WITHIN the existing .amc-* tokens. No competing design system, no raw hex beyond the
   neutral rgba shadows already in the palette, and the reserved semantic colours (green = complete,
   red/Fuchsia = QC fail, orange = carry-forward, Citrus = selected) are never reassigned. Motion is
   gated by prefers-reduced-motion at the end of this block. */

/* Motion: interactive surfaces ease their hover/active feedback instead of snapping. These selectors
   already exist above with their resting styles; this only adds the transition + a restrained hover
   lift, so the cascade merges (no override of colours/state). */
.amc-btn,.amc-ops-card,.amc-card,.amc-pending,.amc-navbtn,.amc-menubtn,.amc-iconbtn,.amc-account,
.amc-locbtn,.amc-chip,.amc-tab,.amc-locopt,.amc-roleopt,.amc-statuspill,.amc-cfg-pill--btn,.amc-drag,
.amc-crumbs__item{transition:background-color .16s var(--ease),border-color .16s var(--ease),color .16s var(--ease),box-shadow .18s var(--ease),transform .16s var(--ease);}
.amc-btn:active{transform:translateY(1px);}
.amc-ops-card{box-shadow:var(--shadow-sm);}
.amc-ops-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);}
.amc-pending:hover{box-shadow:var(--shadow-sm);}
.amc-card:hover{box-shadow:var(--shadow-sm);}

/* Skeleton loading — a real loading state (replaces "Loading…" text on the React drill-downs). Neutral
   shimmer between two surface tokens; carries aria-hidden in markup with an adjacent .amc-sr live label. */
@keyframes amc-shimmer{from{background-position:-180px 0;}to{background-position:260px 0;}}
.amc-skel{position:relative;border-radius:var(--radius-sm);background:linear-gradient(90deg,var(--surface-2) 0%,var(--chip-surface) 50%,var(--surface-2) 100%);background-size:300px 100%;animation:amc-shimmer 1.15s linear infinite;}
.amc-skel--title{height:24px;width:min(260px,58%);margin:2px 0 4px;}
.amc-skel--sub{height:13px;width:min(360px,80%);margin:0 0 4px;}
.amc-skel--line{height:13px;margin:8px 0;}
.amc-skel--line.is-short{width:44%;}
.amc-skel--line.is-mid{width:70%;}
.amc-skelblock{display:flex;flex-direction:column;gap:6px;}
.amc-skelcard{background:var(--surface);border:1px solid var(--border);border-radius:13px;padding:15px;display:flex;flex-direction:column;gap:10px;}
.amc-skel-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px 16px;}
.amc-skel-grid .amc-skel--line{margin:0;height:30px;}
/* POLISH-LOADSTATE-001 list skeleton. Every row height below is DERIVED, never hand-written. Each one was
   produced by MOUNTING THE REAL component (JobsAdminApp / ServiceLocationsApp / QcReviewApp) under this same
   APP_CSS, parking its one primary list fetch, measuring the skeleton row, releasing the fetch, and reading
   getBoundingClientRect().height off the settled row the deployed oracle actually targets. Authored markup
   is NOT an acceptable source for these numbers — it is what made the first cut wrong.
   Subjects are the exact rows scripts/harness-ui-test-worker.mjs seeds at MARK_COMPLETE.locId.
   PHONE CONSTANTS ARE DEPLOYED-DERIVED. The first cut measured a LOCAL mount of the real components with
   harness-SHAPED fixture strings, swept across RUN-token widths 9..14, and got route 54.5 / qc 110. The
   first execution of tests/ui/list-loading-skeleton.spec.ts against the DEPLOYED test Worker contradicted
   both, because the local rig's assumption about WHICH row settles first was wrong about the real fixture:
     route -> the settled first .amc-route tbody tr[data-sl-id] measures 99.25px on the deployed build
              (settled species cluster at 99.25, 118 and 173), not the 54.5px the local mount produced.
     qc    -> the R5-O-QCFAIL rework row measures 86px. NOTE (corrected 2026-08-20): this line used to
              claim openReworks is NOT empty and that the rework row leads the list. It does not — the
              fixture COMPLETES the rework it spawns, so /api/qc-review returns openReworks:[] and that
              86px row renders LAST under "Recently resolved reworks". The list is LED by carry-forward
              obligations, whose RUN-token-bearing names make them 110/111px 3-line-name rows. The
              constant was right; the oracle's "measure whichever row is first" subject was wrong.
   A local mount cannot settle this question; the deployed measurement is the authority and is what these
   numbers now record.
   Measurements (constant -> settled, delta):
     phone 390px  (DEPLOYED lane-2, Chromium mobile emulation 390x844; named subjects):
                    jobs 49 -> 50.5 (1.5) | route 99 -> 99.25 (0.25) | qc 86 -> 86.0 (0)
     desktop 1280 (LOCAL real-component mount, 2026-08-06, RUN-width sweep 9..14 — the deployed parity
                    oracle is phone-only, so these stay at their local derivation and are pinned, not proven):
                    jobs 49 -> 49.0 (0) | route 48 -> 45.0 (3) | qc 40 -> 40.0 (0)
   Settled list rows are CONTENT-sized, so a constant is only honest for a named subject and a named
   fixture: the same QC row species measures 62/86/110/134/158 across stop-name lengths, and the deployed
   route species span 98.25..173. Re-derive against the DEPLOYED component whenever a row's markup or the
   harness subject changes; never hand-tune toward a passing number and never widen the 8px tolerance.
   SKEL-FIXTURE-001 — the phone parity oracle used to compare a fixed constant against whichever row the
   fixture happens to render FIRST, so an unrelated harness fixture change moved it. QC is FIXED (2026-08-20):
   tests/ui/list-loading-skeleton.spec.ts now names its settled subject (the R5-O-QCFAIL rework row, whose
   rendered identity carries no RUN token) and settledSubjectSelector must match exactly one row.
   FID-024 closes the route residual with a dedicated RUN-free Route Parity / 9 Parity Way stop of the
   99.25px species the existing 99px constant mimics. This follows the QC precedent: stabilize the subject,
   do not retune the product constant. The committed negative control injects 118px and requires the same
   named-subject metric to go red before removal restores parity.
   Jobs is unaffected — its rows carry a declared height, so every row is one species.
   Guards: test/unit/list-skeleton-css.test.ts pins these constants; tests/ui/list-loading-skeleton.spec.ts
   is the real-mount parity oracle against the deployed build. */
.amc-listskel__rows{overflow:hidden;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);}
.amc-listskel__row{display:grid;align-items:center;gap:10px 14px;padding:0 12px;border-top:1px solid var(--divider);}
.amc-listskel__row:first-child{border-top:0;}
.amc-listskel__row .amc-skel--line{height:12px;margin:0;width:100%;}
.amc-listskel--jobs .amc-listskel__row{height:49px;grid-template-columns:1.1fr 1fr .7fr;}
.amc-listskel--route .amc-listskel__row{height:99px;grid-template-columns:1fr;}
.amc-listskel--qc .amc-listskel__row{height:86px;grid-template-columns:1fr;}
/* Jobs/Route settle INTO a bordered card (.amc-cfg-gridwrap/.amc-route-wrap both measure border 1px,
   radius 11px, surface), but QC settles into a bare .amc-qcr-list (border 0, radius 0, transparent) whose
   own rows carry the surface — so the QC skeleton drops the card chrome instead of jumping card -> list. */
.amc-listskel--qc .amc-listskel__rows{overflow:visible;border:0;border-radius:0;background:transparent;display:flex;flex-direction:column;gap:1px;}
.amc-listskel--qc .amc-listskel__row{background:var(--surface);}
@media (min-width:721px) and (pointer:fine){
  .amc-listskel--route .amc-listskel__row{height:48px;grid-template-columns:1.1fr 1fr .7fr;}
  .amc-listskel--qc .amc-listskel__row{height:40px;grid-template-columns:1.1fr 1fr .7fr;}
}

/* Breadcrumb trail — the up-the-hierarchy companion to the NAV-001 "Show in ___ list" links, on the
   drill-down pages (work list/jobs/route order → this record). Owner round 2 (item f): the trail scrolls
   HORIZONTALLY rather than wrapping when long (so a long "Customer › Weekday Address › Job › Visit" path
   stays one tidy line); only the final crumb is bold (the current page). */
.amc-crumbs{display:flex;flex-wrap:nowrap;align-items:center;gap:2px;margin:0 0 12px;font-size:13px;color:var(--text-muted);min-width:0;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;-webkit-overflow-scrolling:touch;}
.amc-crumbs > span{flex:none;}
.amc-crumbs__item{display:inline-flex;align-items:center;max-width:30ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-muted);text-decoration:none;border-radius:6px;padding:2px 6px;}
a.amc-crumbs__item:hover{color:var(--text);background:var(--chip-surface);}
a.amc-crumbs__item:focus-visible{outline:2px solid var(--focus);outline-offset:1px;}
/* A non-link ancestor crumb (e.g. the customer head before its page exists): muted, NOT bold — only the
   final crumb is the current page. */
.amc-crumbs__ancestor{display:inline-flex;align-items:center;max-width:30ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-muted);padding:2px 6px;}
.amc-crumbs__sep{color:var(--text-faint);flex:none;padding:0 1px;user-select:none;}
.amc-crumbs__current{font-weight:700;color:var(--text);padding:2px 6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:40ch;}

/* ===== SORT-004 (scroll-ownership law, motion-and-continuity-laws.md) ===== */
/* Framed screens (/jobs-admin, /service-locations): the page fits the viewport and the grid frame
   owns ALL scrolling — replacing hardcoded viewport-minus-header guesses that ignored the back-link/
   head/toolbar heights (the OR-4 double-scroll root cause). The chain: viewport-height app column →
   canvas clips → React mount + page become flex columns → the wrap flexes to the leftover space. */
.amc-app--framed{height:100vh;height:100dvh;max-width:100vw;overflow:hidden;display:flex;flex-direction:column;}
.amc-app--framed .amc-canvas{flex:1;min-width:0;min-height:0;max-width:100%;overflow:hidden;display:flex;flex-direction:column;}
.amc-app--framed .amc-canvas>div[id]{flex:1;min-width:0;min-height:0;max-width:100%;overflow:hidden;display:flex;flex-direction:column;}
.amc-app--framed .amc-page{flex:1;min-width:0;min-height:0;max-width:100%;overflow:hidden;display:flex;flex-direction:column;width:100%;}
.amc-app--framed .amc-cfg-gridwrap,.amc-app--framed .amc-route-wrap{flex:1;min-width:0;min-height:120px;max-width:100%;max-height:none;overflow:auto;}
/* Phones keep the pre-existing single window-scroll flow (the <=720px rules already drop the inner
   frame heights). A short coarse-pointer landscape device follows that phone flow too; a short
   fine-pointer/tiled desktop remains framed so the table is still its one contractual scroll owner. */
@media (max-width:720px), (max-height:520px) and (pointer:coarse){
  .amc-app--framed{height:auto;max-width:none;overflow:visible;display:block;}
  .amc-app--framed .amc-canvas{overflow:visible;display:block;}
  .amc-app--framed .amc-canvas>div[id]{max-width:none;overflow:visible;display:block;}
  .amc-app--framed .amc-page{max-width:calc(100vw - 24px);overflow:visible;display:block;}
  .amc-app--framed .amc-cfg-gridwrap,.amc-app--framed .amc-route-wrap{min-height:0;}
}
/* CONTAINMENT LAW (SL-OVERFLOW-001) — a horizontal scroll frame must also be a CONTAINING BLOCK. Unscoped
   on purpose: the frames above own scrolling only while overflow:auto is in force, but this half of the
   contract must hold in the framed AND the phone/window-scroll flows.
   overflow clips a descendant only when the frame is in that descendant's containing-block chain, so an
   absolutely positioned box inside a STATIC frame skips the frame and resolves against the nearest
   positioned ancestor — .amc-canvas (~line 263) for all of these — contributing its full static position
   to the CANVAS's scrollable overflow while the frame it visually lives in reports itself contained.
   Measured on the deployed mobile lane at 390x844 (OFR-R4 merge boundary, 2026-08-06): Route Order's 36
   per-row <label class="amc-sr"> weekday labels (RouteOrderApp.tsx) sat at the weekday column's content
   edge x=475, inside a 520px table in a 328px frame; nothing clipped them; body.scrollWidth read 475
   against a 390 client width, and Chromium's minimum-scale shrink-to-fit then laid the whole page out at
   476x1028 — which is why a keyboard-safe popover read as a boundary violation in device pixels. The Jobs
   grid escaped only by accident: its one in-grid absolute box (.amc-cfg-grid__resize) hangs off a
   position:sticky TH, already a containing block. Deliberate escapes are unaffected — the popovers that
   must overflow these frames are position:FIXED (.amc-cfg-pop__panel/__backdrop) or portalled, and
   neither resolves against a relative ancestor. No z-index, so no stacking context, no paint-order change. */
.amc-tablewrap,.amc-cfg-gridwrap,.amc-route-wrap{position:relative;}
/* SORT-004 width: Route Order keeps the same Jobs Configuration width model in BOTH modes (P2's
   geometry-invariance law). The work list keeps its wider sort-only reading model and window scroll. */
.amc-mcpage[data-sort-mode="on"]{max-width:calc(100vw - 24px);}
@media (max-width:720px){
  /* Work-list Sort is the compact phone planning surface: use the promised minimal gutter instead of
     stacking a 12px auto-margin outside the page's ordinary 18px padding. */
  .amc-mcpage[data-sort-mode="on"]{width:100%;max-width:100%;padding-inline:12px;}
}

/* ===== M-1..M-12 (motion-and-continuity-laws.md) — shared continuity motion ===== */

/* Sheet/dialog entrance + exit. ENTRANCES run for every RAC modal regardless of dialog class, and
   hand-rolled .amc-overlay dialogs (+ the legacy server-tier overlays toggled via [hidden]) inherit
   them for free. EXITS are honest-scoped (Codex correction 7): React Aria can only stamp
   data-exiting and delay unmount for callers that KEEP the Modal mounted and flip its open prop
   (AssignDialog, the Modal-based confirms). The dominant "open && <Sheet/>" callers unmount the
   whole component on close, so those sheets close instantly BY CONSTRUCTION — do not claim
   otherwise, and do not mass-rewrite call sites to chase the exit (recorded decision). Restrained
   transform/opacity only — no bounce, no long fades (M-11). */
@keyframes amc-overlay-in{from{opacity:0;}to{opacity:1;}}
@keyframes amc-overlay-out{from{opacity:1;}to{opacity:0;}}
@keyframes amc-modal-in{from{opacity:0;transform:translateY(8px) scale(.985);}to{opacity:1;transform:none;}}
@keyframes amc-sheet-in{from{opacity:0;transform:translateY(26px);}to{opacity:1;transform:none;}}
.amc-overlay{animation:amc-overlay-in var(--motion-fade) var(--ease-out);}
/* pointer-events:none while exiting (M-6): the fading full-screen backdrop must never swallow the
   tap that follows a close — the dialog inside inherits inertness from this one ancestor rule. */
.amc-overlay[data-exiting]{animation:amc-overlay-out var(--motion-fade) var(--ease) forwards;pointer-events:none;}
/* The wrap itself is display:contents (no box — it exists so the dialog is a direct flex item of the
   overlay), so entrance motion targets its CHILD, the real dialog card, whatever its class. */
.amc-overlay__wrap>*{animation:amc-modal-in var(--motion-sheet) var(--ease-out);}
.amc-overlay--bottom .amc-overlay__wrap>*{animation:amc-sheet-in var(--motion-sheet) var(--ease-out);}
.amc-overlay__wrap[data-exiting]>*{animation:amc-overlay-out var(--motion-fade) var(--ease) forwards;}

/* WORKLIST-002 — hoist legibility: the sticky filter-bar mode chip renders in BOTH non-route hoist
   modes; only the per-row "moved up" sub-badge is weekday_top-specific. list_top uses its distinct
   group header and tinted REAL-day chip instead of duplicating it. The cue is icon + text, never
   colour alone, and the durable route order is unchanged. */
/* R5-V-FILTER-LABEL: inside the collapsed filter toggle this chip is the designated yielder. It was
   flex:none, so on a narrow head it held its full width and pushed the fixed count out of the control.
   The purpose label and the matched/total count are load-bearing; an abbreviated hoist chip is not.
   MERGE NOTE (final fold, 2026-08-06): WORKLIST-002 branched before this fix and still carried the
   original flex:none. Its intent was the comment above, not the declaration, so the yielder behaviour
   is preserved here rather than silently reverted. */
.amc-hoistmode{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;display:inline-flex;align-items:center;gap:3px;padding:1px 8px;border:1px solid var(--flag-carry);border-radius:999px;color:var(--flag-carry);background:var(--surface);font-size:11.5px;font-weight:700;white-space:nowrap;}
.amc-flagbadge__hoist{display:inline-flex;align-items:center;gap:2px;margin-left:6px;padding-left:6px;border-left:1px solid currentColor;font-weight:700;}

/* Toast exit (N3 keeps success non-blocking): a short fade-down played before unmount; errors and
   refusals still persist until Close (N2) — this only softens the removal that already happens. */
@keyframes amc-toast-out{from{opacity:1;transform:translate(-50%,0);}to{opacity:0;transform:translate(-50%,6px);}}
.amc-toast[data-closing="yes"]{animation:amc-toast-out var(--motion-fade) var(--ease) forwards;}

/* Disclosure primitive (M-10) — MeasuredDisclosure writes concrete start/end heights, captures the
   current rendered height on reversal, and returns a settled open surface to auto. The outer clip is
   active only while closed/travelling; rich content is fully visible after settle. flow-root keeps
   child margins inside the measured content box (not collapsed outside it). Arm the transition only
   while the component reports real motion: initial measurement and settled resize corrections must
   snap to their authoritative endpoint instead of playing an untracked load-time transition. */
.amc-disclose{height:0;min-height:0;overflow:hidden;overflow:clip;}
.amc-disclose[data-animating="yes"]{transition:height var(--motion-disclose) var(--ease);}
.amc-disclose__content{min-height:0;display:flow-root;}
.amc-retained-rich{display:contents;}
.amc-disclose[data-open="yes"][data-animating="no"]{overflow:visible;}
.amc-error-details__toggle{width:auto;min-height:0;padding:2px 0;font-size:12px;}
.amc-error-details__code{display:block;margin-top:4px;padding:6px 8px;border-radius:6px;background:var(--surface-2);overflow-wrap:anywhere;white-space:pre-wrap;}

/* R5-H7-AUTOZOOM — iOS zooms a focused FORM CONTROL below 16px, and a select IS one: Safari zooms on
   a focused native picker exactly as it does on a text input. Keep the phone tier's computed size at
   the platform-safe minimum across native inputs, selects, textareas, and rich editors.

   The select rule is here DELIBERATELY and AGAINST the chunk-spec's oracle clause, which enumerated
   only input/textarea/[contenteditable]. That clause contradicted this chunk's own title ("every
   phone text-entry control") and left two real sub-16px focusable selects unprotected:
   .amc-route__weekdaysel (explicit 12.5px, declared above) and .amc-select--sm (no rule at all, UA
   default ~13px — src/client/visit-detail/VisitDetailApp.tsx:564). The narrow clause is OVERWRITTEN
   rather than preserved (AGENTS.md spec-conflict rule).

   The class overrides are the inventoried higher-specificity declarations that would otherwise beat
   the element rule — .amc-route__weekdaysel's own 0,1,0 rule is exactly that case. Desktop keeps its
   intentionally dense planning-grid typography. */
@media (max-width:720px){
  input{font-size:16px;}
  select{font-size:16px;}
  textarea{font-size:16px;}
  [contenteditable]{font-size:16px;}
  .amc-field--code,.amc-import__textarea,.amc-cfg-cellinput,.amc-cfg-instredit,.amc-filterrow__date,.amc-route__weekdaysel{font-size:16px;}
}

/* FLIP row travel (SORT-005, M-2/M-9): the helper in src/client/motion/flip.ts sets the inverted
   transform inline, opens the owning list's ordinary overflow clip, then adds this class and plays the
   transform. Transition-only (no keyframe) so an interrupted toggle simply re-targets mid-flight. */
.amc-flip-travel{transition:transform var(--motion-flip) var(--ease-out);}
.amc-flip-travel--lens-exit{transition-duration:var(--motion-flip-lens);}
/* D19 (owner pick, 2026-08-20): the work list's ENTRY into Visits/Jobs sort owns its own token so the
   pick cannot retime the other --motion-flip consumers (same-lens local projection, context travel,
   Jobs Config and Route Order sort). Easing stays --ease-out from the base rule above. */
.amc-flip-travel--sort-entry{transition-duration:var(--motion-flip-sort-entry);}

/* CFLABEL-001 — Visit-detail overflow action; native details keeps the kebab keyboard-operable. */
.amc-detail-kebab{position:relative;}
.amc-detail-kebab>summary{list-style:none;display:inline-flex;align-items:center;justify-content:center;min-width:44px;cursor:pointer;}
.amc-detail-kebab>summary::-webkit-details-marker{display:none;}
.amc-detail-kebab__menu{position:absolute;right:0;top:calc(100% + 6px);z-index:20;min-width:190px;padding:6px;border:1px solid var(--border-strong);border-radius:var(--radius);background:var(--surface);box-shadow:var(--shadow-pop);}
.amc-detail-kebab__menu button{width:100%;min-height:44px;padding:8px 10px;border:0;border-radius:8px;background:transparent;color:var(--text);text-align:left;cursor:pointer;}
.amc-detail-kebab__menu button:hover{background:var(--surface-2);}

/* L3-PHONEHOME-PROBE — compact test-only guided capture + evidence readout. */
.amc-phoneprobe{gap:12px;padding-top:12px;padding-bottom:36px;}
.amc-phoneprobe__head{display:flex;flex-direction:column;gap:2px;}
.amc-phoneprobe__head .amc-page__subtitle{margin:0;}
.amc-phoneprobe__startcard{gap:10px;padding:12px;}
.amc-phoneprobe__label{display:flex;flex-direction:column;gap:4px;font-size:14px;font-weight:700;}
.amc-phoneprobe__label .amc-meta{font-weight:400;line-height:1.35;}
.amc-phoneprobe__stage{scroll-margin-top:8px;}
.amc-phoneprobe__stage p,.amc-phoneprobe__claim{margin:0;font-size:14px;line-height:1.5;color:var(--text-muted);}
.amc-phoneprobe__keyboard{display:flex;flex-direction:column;gap:10px;}
.amc-phoneprobe__runway{min-height:140vh;border:1.5px dashed var(--border-strong);border-radius:var(--radius);background:var(--surface-2);display:flex;flex-direction:column;align-items:center;justify-content:space-around;padding:20px;color:var(--text-faint);font-size:12px;text-transform:uppercase;letter-spacing:.04em;}
.amc-phoneprobe__signals{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px;}
.amc-phoneprobe__signal{display:flex;flex-direction:column;gap:4px;padding:11px;border:1px solid var(--border);border-radius:10px;background:var(--surface-2);min-width:0;}
.amc-phoneprobe__signal strong{font-size:16px;}
.amc-phoneprobe__signal .amc-meta{overflow-wrap:anywhere;}
.amc-phoneprobe__samples summary{display:flex;align-items:center;min-height:44px;font-weight:700;cursor:pointer;}
.amc-phoneprobe__sampletable{width:100%;border-collapse:collapse;font-size:12px;min-width:620px;}
.amc-phoneprobe__sampletable th,.amc-phoneprobe__sampletable td{text-align:left;padding:8px;border-bottom:1px solid var(--divider);white-space:nowrap;}
.amc-phoneprobe__sampletable th{background:var(--surface-2);font-size:10px;text-transform:uppercase;letter-spacing:.03em;}
.amc-phoneprobe__run{width:100%;min-height:52px;display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 10px;border:1px solid var(--border);border-radius:10px;background:var(--surface);color:var(--text);text-align:left;cursor:pointer;}
.amc-phoneprobe__run>span:first-child{display:flex;min-width:0;flex-direction:column;gap:2px;}
.amc-phoneprobe__run strong{overflow-wrap:anywhere;}
@media (max-width:600px){.amc-phoneprobe__signals{grid-template-columns:1fr;}}

/* Honour the OS "reduce motion" setting: keep the UI legible but drop the shimmer + transitions/lifts. */
@media (prefers-reduced-motion:reduce){
  *,::before,::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;}
  .amc-ops-card:hover,.amc-btn:active{transform:none;}
}

/* QC-SWIPE-001 (DF-011 amendment, 2026-09-16) — the COMPLETED row's REVEAL-ONLY manager swipe.
   APPEND-ONLY: every rule here is new; nothing above is restyled.
   .amc-jobrow--done is itself the horizontal flex row, so the gesture wrapper becomes its single flex
   child and .amc-jobrow__donebody restores the [🚨 slot | text column] row the row used to be. */
.amc-jobrow--done>.amc-jobrow__swipe{flex:1 1 0;min-width:0;}
.amc-jobrow__donebody{flex:1 1 auto;min-width:0;display:flex;align-items:flex-start;}
/* No bound gesture (crew, or Sort) means no 104px action panel is rendered, so the track must not keep
   the offset geometry that panel pays for — otherwise the content column would sit 104px off the left
   edge. Same shape as the existing --sort reset, which the inline transform likewise needs !important
   to beat. */
.amc-jobrow__swipe--inert .amc-jobrow__swipetrack{width:100%;transform:none!important;touch-action:auto;}
/* Sort keeps the wrapper MOUNTED (identity/disclosure continuity, as the open row does), but the 46px
   sort-row height must stay definite down the new chain, or the height:100% on
   .amc-jobrow--sort .amc-jobrow__text resolves to auto. Scoped to done+sort, so the OPEN sort row's
   geometry is untouched. */
.amc-jobrow--done.amc-jobrow--sort .amc-jobrow__swipe,
.amc-jobrow--done.amc-jobrow--sort .amc-jobrow__swipetrack,
.amc-jobrow--done.amc-jobrow--sort .amc-jobrow__donebody{height:46px;min-height:46px;overflow:hidden;}
/* Reserved-red separation (the amendment's own clause): this is the ACTION — a filled panel with a VERB
   label, present only while the row is held or settled open — never the muted "this row IS QC-failed"
   status paint of .amc-jobrow--qcfailed / .amc-jobrow__status--qcfailed. White on --flag-rework measures
   5.4:1. There is deliberately NO [data-swipe-commit] variant: a reveal-only pull has no commit state. */
.amc-swipeaction--qcfail{--swipe-paint:var(--flag-rework);background:var(--swipe-paint);}
