@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url('/landing/assets/contractor-app/outfit-latin.woff2') format('woff2');
}

/* Instrument workbench: dark reads by default, light writes by choice.
   Both grounds sit on the kit's cool neutral axis (A-9 §A9-1) — INSTRUMENT for
   dark, SHEET for light. Nothing here invents a hue: the only chromatic areas
   in the product are the one orange fill and the paper-white document. Blue is
   a stroke or a numeral, never a field. */
:root,
html[data-theme='dark'] {
  color-scheme: dark;
  /* INSTRUMENT — ink-black ground, graphite raised, charcoal banded. The step
     from ground to raised is the elevation (A0·4); no blur does that work. */
  --bg: #0C0F10;
  --canvas: #0C0F10;
  --sheet: #161A1C;
  --surface: #161A1C;
  --surface-2: #22272A;
  --graphite: #161A1C;
  --charcoal: #22272A;
  --slate: #343A3E;
  --border: rgba(242, 245, 247, .15);
  --border-soft: rgba(242, 245, 247, .10);
  --border-strong: rgba(242, 245, 247, .28);
  --text: #F2F5F7;
  --text-2: #A8B2BA;
  --text-3: #8A939B;
  --datum: #5E9FBF;
  --accent: #8FC3DA;
  --accent-pressed: #5E9FBF;
  --accent-wash: #22272A;
  --on-orange: #0C0F10;
  --orange-soft: #22272A;
  --orange-line: rgba(242, 245, 247, .13);
  --green: #4AD07E;
  --green-soft: #22272A;
  --amber: #E8C838;
  --amber-soft: #22272A;
  --red: #FF6B5E;
  --red-soft: #22272A;
  --solid-bg: #F2F5F7;
  --solid-fg: #0C0F10;
  --solid-bg-hover: #F8FAFA;
  --hairline-dark: inset 0 1px 0 rgba(255, 255, 255, .10);
  --hairline-up: inset 0 1px 0 rgba(255, 255, 255, .08);
  --shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
  --shadow-hover: inset 0 1px 0 rgba(255, 255, 255, .12);
  --cast: 0 20px 44px -20px rgba(0, 0, 0, .78);
  --ring: 0 0 0 2px rgba(94, 159, 191, .46);
  --focus: #8FC3DA;
}

html[data-theme='light'] {
  color-scheme: light;
  /* SHEET — the kit's paper ramp, cool and achromatic: canvas is the desk,
     surface is the sheet lying on it, surface-2 is a band ruled across that
     sheet. Every wash below is the same band tone; a tinted field would make
     status a colour area, which the kit does not have. */
  --bg: #E4E8EA;
  --canvas: #E4E8EA;
  --sheet: #EFF2F3;
  --surface: #F8FAFA;
  --surface-2: #EAEEF0;
  --graphite: #161A1C;
  --charcoal: #22272A;
  --slate: #343A3E;
  --border: #D3D8DA;
  --border-soft: #E2E7E9;
  --border-strong: #B9C0C3;
  --text: #1A1F22;
  --text-2: #545E66;
  --text-3: #77828A;
  --datum: #5E9FBF;
  --accent: #3E6E86;
  --accent-pressed: #32586B;
  --accent-wash: #EAEEF0;
  --on-orange: #0C0F10;
  --orange-soft: #EAEEF0;
  --orange-line: #D3D8DA;
  --green: #166534;
  --green-soft: #EAEEF0;
  --amber: #725B10;
  --amber-soft: #EAEEF0;
  --red: #B91C1C;
  --red-soft: #EAEEF0;
  --solid-bg: #1A1F22;
  --solid-fg: #F8FAFA;
  --solid-bg-hover: #0C0F10;
  --hairline-dark: inset 0 1px 0 rgba(255, 255, 255, .10);
  --hairline-up: inset 0 1px 0 rgba(255, 255, 255, .55);
  --shadow: 0 1px 2px rgba(12, 15, 16, .06);
  --shadow-hover: 0 4px 12px -2px rgba(12, 15, 16, .13);
  --cast: 0 18px 40px -18px rgba(12, 15, 16, .35);
  --ring: 0 0 0 2px rgba(62, 110, 134, .32);
  --focus: #1A1F22;
}

html,
body,
button,
input,
select,
textarea {
  font-family: 'Outfit', ui-sans-serif, system-ui, -apple-system, sans-serif;
}

body {
  background: var(--bg);
  color: var(--text);
}

button:focus-visible,
a:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
.chip:focus-visible,
.btn:focus-visible,
.backlink:focus-visible,
.chat-fab:focus-visible {
  outline-color: var(--focus);
}

::selection {
  background: var(--datum);
  color: #0C0F10;
}

#boot-splash,
#auth-screen,
#role-gate {
  background: var(--canvas);
}

.auth-card,
.sidebar,
.card,
.tbl-wrap,
.modal,
.chat-fab,
.tool-row,
.sch-ag-entry,
#screen-invoices .inv-pick {
  background: var(--surface);
  color: var(--text);
}

.sidebar {
  border-color: var(--border);
}

/* The rail is furniture, not paper. It holds the same graphite in both themes
   so the thing you navigate by never moves underneath you — only the sheet you
   are working on changes when the theme does. Redeclaring the shared tokens on
   the aside is what does it: everything inside inherits these instead of the
   theme's, so no sidebar rule needs to know a theme exists. Nothing but the
   rail lives in here (no popovers, no menus), so the override cannot leak. */
.sidebar {
  color-scheme: dark;
  --bg: #161A1C;
  --canvas: #161A1C;
  --sheet: #22272A;
  --surface: #22272A;
  --surface-2: #2C3235;
  --graphite: #2C3235;
  --border: rgba(242, 245, 247, .13);
  --border-soft: rgba(242, 245, 247, .08);
  --border-strong: rgba(242, 245, 247, .24);
  --text: #F2F5F7;
  --text-2: #A8B2BA;
  --text-3: #8A939B;
  /* The light theme's accent and focus are near-black by design — on graphite
     they would be a hover state you cannot see and a focus ring you cannot
     find. Both take the dark theme's emitted-light values here. */
  --accent: #8FC3DA;
  --accent-pressed: #5E9FBF;
  --focus: #8FC3DA;
  --ring: 0 0 0 2px rgba(94, 159, 191, .46);
  --hairline-up: inset 0 1px 0 rgba(255, 255, 255, .07);
  --shadow: inset 0 1px 0 rgba(255, 255, 255, .05);
}

.side-brand {
  min-height: 58px;
}

.side-item {
  min-height: 46px;
  color: var(--text-2);
  transition: background-color 160ms var(--ease-out), color 160ms var(--ease-out);
}

.side-item svg {
  opacity: .78;
}

.side-item.active {
  background: var(--surface-2);
  color: var(--text);
  box-shadow: var(--hairline-up);
}

.side-item.active::before {
  width: 1px;
  background: var(--orange);
}

.side-toggle,
.btn,
.chip,
.chat-fab,
.theme-option {
  transition-property: background-color, border-color, color, box-shadow, transform;
  transition-duration: 160ms;
  transition-timing-function: var(--ease-out);
}

.btn:active,
.chip:active,
.chat-fab:active,
.theme-option:active {
  transform: scale(.97);
}

.side-toggle:active {
  transform: scale(.95);
}

.screen.on {
  animation: none;
}

.main {
  padding-top: 40px;
}

.content {
  max-width: 1320px;
}

.page-h h1 {
  color: var(--text);
  font-size: clamp(28px, 2.2vw, 34px);
  font-weight: 700;
  letter-spacing: -.03em;
}

.sec-h {
  margin-bottom: 14px;
}

.sec-h h2 {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -.02em;
}

.sec-h .sec-link {
  color: var(--accent);
}

.card {
  border-color: var(--border);
  box-shadow: var(--shadow);
}

.card.click {
  transition-property: border-color, box-shadow, transform;
  transition-duration: 180ms;
  transition-timing-function: var(--ease-out);
}

.badge {
  background: var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--border);
}

.btn-ghost,
.chip,
.search,
.wsel {
  background: var(--surface);
  color: var(--text);
}

.btn-ghost:active,
.side-item:active {
  background: var(--surface-2);
}

.tbl th,
.sch-day.weekend,
.pdx-file:hover,
.pdx-schrow-btn:hover,
#screen-project-detail .tab:hover {
  background: var(--surface-2);
}

.bar,
.cw-bar,
.sug-tag {
  background: var(--canvas);
}

input:not([type='checkbox']):not([type='radio']):not([type='color']),
textarea,
select,
.ee-in,
.pr-notes-ta,
.brand-hex,
.brand-select,
#screen-invoices .inv-in {
  background-color: var(--surface);
  color: var(--text);
}

input::placeholder,
textarea::placeholder {
  color: var(--text-3);
  opacity: 1;
}

.skel {
  background: var(--surface-2);
}

.skel::after {
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text) 10%, transparent), transparent);
}

.switch .sw-knob {
  background: var(--border-strong);
  transition: background-color 180ms var(--ease-out);
}

.switch .sw-knob::after {
  background: var(--text);
  border: 3px solid var(--surface);
  box-shadow: none;
  transition: transform 180ms var(--ease-out);
}

.switch input:checked + .sw-knob {
  background: var(--orange);
}

/* Dashboard: operational hierarchy, not a marketing composition. */
#screen-dashboard .dash-page-h {
  align-items: center !important;
  margin-bottom: 40px;
}

#screen-dashboard .dash-date {
  margin-top: 7px;
  color: var(--text-2);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .01em;
}

#screen-dashboard .dash-actions {
  gap: 10px !important;
}

#screen-dashboard .sec {
  margin-bottom: 34px;
}

#screen-dashboard .empty {
  min-height: 170px;
  padding: 28px;
  border-style: solid;
  border-color: var(--border);
  background: var(--surface);
}

#screen-dashboard #dash-active .empty {
  min-height: 128px;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 18px;
  row-gap: 3px;
  padding: 24px;
  text-align: left;
}

#screen-dashboard #dash-active .empty .e-ico {
  grid-column: 1;
  grid-row: 1 / 3;
  width: 44px;
  height: 44px;
  margin: 0;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface-2);
  box-shadow: none;
}

#screen-dashboard #dash-active .empty .e-t {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  font-size: 17px;
  font-weight: 600;
}

#screen-dashboard #dash-active .empty .e-s {
  grid-column: 2;
  grid-row: 2;
  max-width: 680px;
  margin: 0;
  color: var(--text-2);
  font-size: 15px;
}

#screen-dashboard #dash-active .empty .btn {
  grid-column: 3;
  grid-row: 1 / 3;
}

#screen-dashboard .empty .e-ico,
#screen-dashboard .li-ico {
  border-radius: 4px;
  background: transparent;
  box-shadow: none;
  color: var(--accent);
}

#screen-dashboard .empty .e-s {
  color: var(--text-2);
  font-size: 15px;
  line-height: 1.5;
}

#screen-dashboard .card.li-card {
  padding: 4px 8px;
}

#screen-dashboard .li-row {
  min-height: 62px;
  padding: 12px 10px;
  transition: background-color 140ms var(--ease-out), transform 120ms var(--ease-out);
}

#screen-dashboard .li-row[data-nav]:active {
  transform: scale(.995);
}

#screen-dashboard .li-ico {
  width: 30px;
  height: 30px;
}

#screen-dashboard .li-row + .li-row::before {
  left: 10px;
  right: 10px;
}

#screen-dashboard .tiny,
#screen-dashboard .card-foot,
#screen-dashboard .photo-strip .ps-cap {
  color: var(--text-2);
  font-size: 13px;
}

#screen-dashboard .photo-strip {
  gap: 14px;
  padding-bottom: 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}

#screen-dashboard .photo-strip::-webkit-scrollbar,
#screen-dashboard .rail::-webkit-scrollbar {
  height: 5px;
}

#screen-dashboard .photo-strip .ps-cell,
#screen-dashboard .photo-strip .ps-thumb {
  width: 216px;
}

#screen-dashboard .photo-strip .ps-thumb {
  height: auto;
  aspect-ratio: 4 / 3;
  border-radius: 10px;
  background: var(--surface);
}

#screen-dashboard .photo-strip .ps-cell img,
#screen-dashboard .photo-strip .ps-cell video {
  position: relative;
  z-index: 1;
  opacity: 1;
  transition: opacity 180ms var(--ease-out), transform 200ms var(--ease-out);
}

#screen-dashboard .photo-strip .ps-thumb.is-loading img,
#screen-dashboard .photo-strip .ps-thumb.is-loading video {
  opacity: 0;
}

#screen-dashboard .ps-fallback {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 8px;
  color: var(--text-3);
  background: var(--surface-2);
  font-size: 13px;
  font-weight: 500;
}

#screen-dashboard .mv-play {
  z-index: 2;
  width: 34px;
  height: 34px;
  border: 1px solid rgba(242, 245, 247, .28);
  border-radius: 4px;
  background: rgba(12, 15, 16, .72);
  color: #F2F5F7;
  font-size: 0;
}

#screen-dashboard .mv-play svg {
  width: 14px;
  height: 14px;
}

#screen-dashboard .card.click:hover {
  transform: none;
  box-shadow: var(--shadow-hover);
}

.theme-control {
  padding: 18px 0 4px;
  border-top: 1px solid var(--border);
}

.theme-control-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 10px;
}

.theme-control-title {
  color: var(--text);
  font-size: 15px;
  font-weight: 600;
}

.theme-control-note {
  color: var(--text-3);
  font-size: 13px;
}

.theme-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface-2);
}

.theme-option {
  min-height: 38px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--text-2);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.theme-option.on {
  background: var(--surface);
  color: var(--text);
  box-shadow: inset 0 -1px 0 var(--datum), var(--hairline-up);
}

@media (hover: hover) and (pointer: fine) {
  .side-item:hover,
  .side-user:hover,
  .btn-ghost:hover,
  .btn-quiet:hover,
  .li-row[data-nav]:hover {
    background: var(--surface-2);
  }

  #screen-dashboard .photo-strip .ps-cell:hover img,
  #screen-dashboard .photo-strip .ps-cell:hover video {
    transform: scale(1.025);
  }
}

@media (max-width: 899px) {
  .sidebar {
    background: color-mix(in srgb, var(--surface) 96%, transparent);
  }

  .side-item.active::before {
    width: auto;
    height: 1px;
  }

  .main {
    padding-top: 30px;
  }
}

@media (max-width: 600px) {
  #screen-dashboard .dash-page-h {
    align-items: stretch !important;
    margin-bottom: 30px;
  }

  #screen-dashboard .dash-actions {
    width: 100%;
  }

  #screen-dashboard .dash-actions .btn {
    flex: 1 1 0;
  }

  #screen-dashboard #dash-active .empty {
    display: grid;
    grid-template-columns: 38px minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    padding: 20px;
  }

  #screen-dashboard #dash-active .empty .e-ico {
    grid-row: 1 / 3;
    width: 38px;
    height: 38px;
  }

  #screen-dashboard #dash-active .empty .btn {
    grid-column: 1 / -1;
    grid-row: 3;
    width: 100%;
    margin-top: 14px;
  }

  #screen-dashboard .photo-strip .ps-cell,
  #screen-dashboard .photo-strip .ps-thumb {
    width: 176px;
  }
}

/* Photo-first project and report feeds. */
.chip.on,
.mt-chip.on {
  border-color: var(--datum);
  background: var(--surface-2);
  color: var(--text);
  box-shadow: inset 0 -2px 0 var(--datum), var(--hairline-up);
}

.project-feed-toolbar,
.project-feed-filters,
.project-feed-actions,
.report-feed-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
}

.project-feed-toolbar {
  justify-content: space-between;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.project-feed-filters,
.project-feed-actions {
  flex-wrap: wrap;
}

.project-feed-actions .search {
  width: min(330px, 42vw);
}

.project-feed-list {
  display: grid;
  gap: 16px;
}

.project-feed-card {
  display: grid;
  grid-template-columns: minmax(280px, .78fr) minmax(460px, 1.42fr);
  min-height: 258px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
  cursor: pointer;
  transition: border-color 160ms var(--ease-out), box-shadow 160ms var(--ease-out), transform 120ms var(--ease-out);
}

.project-feed-card:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

.project-feed-copy {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 22px;
  border-right: 1px solid var(--border);
}

.project-feed-titleline,
.dash-project-titleline {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.project-feed-name {
  margin: 0;
  color: var(--text);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -.02em;
}

.project-feed-address {
  margin-top: 4px;
  color: var(--text-2);
  font-size: 13px;
}

.project-feed-meta {
  display: grid;
  gap: 5px;
  margin-top: 24px;
  color: var(--text-2);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.project-feed-meta strong {
  color: var(--text);
  font-weight: 600;
}

.project-feed-signals {
  display: flex;
  flex-wrap: wrap;
  gap: 7px 14px;
  margin-top: 15px;
  color: var(--text-2);
  font-size: 12px;
}

.project-feed-signals span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.project-feed-open,
.dash-project-open,
.dash-project-more {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}

.project-feed-open {
  margin-top: auto;
  padding-top: 18px;
}

.project-feed-media {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  min-width: 0;
  background: var(--canvas);
}

.project-feed-media-cell {
  position: relative;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  border-right: 1px solid var(--surface);
  border-bottom: 1px solid var(--surface);
  background: var(--surface-2);
}

.project-feed-media-cell img,
.project-feed-media-cell video,
.report-media-cell img,
.report-media-cell video,
.project-report-media-cell img,
.project-report-media-cell video {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  transition: transform 160ms var(--ease-out);
}

.dash-project-media img,
.dash-project-media video {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

.project-feed-media-cell time {
  position: absolute;
  right: 7px;
  bottom: 7px;
  padding: 3px 6px;
  border-radius: 4px;
  background: rgba(12, 15, 16, .78);
  color: #F2F5F7;
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.project-feed-play,
.report-media-play {
  position: absolute;
  z-index: 2;
  inset: 50% auto auto 50%;
  display: grid;
  width: 30px;
  height: 30px;
  place-items: center;
  border: 1px solid rgba(242, 245, 247, .28);
  border-radius: 4px;
  background: rgba(12, 15, 16, .76);
  color: #F2F5F7;
  transform: translate(-50%, -50%);
}

.project-feed-empty-media {
  grid-column: 1 / -1;
  grid-row: 1 / -1;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 8px;
  color: var(--text-3);
  font-size: 13px;
}

/* Global Reports: chronological feed first, reporters as a supporting rail. */
.report-feed-loading .card-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.report-feed-toolbar {
  justify-content: flex-start;
  flex-wrap: wrap;
  margin: -6px 0 22px;
}

.report-feed-search {
  width: min(420px, 48vw);
}

.report-workspace {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 276px;
  grid-template-areas: 'feed reporters';
  align-items: start;
  gap: 24px;
}

.report-feed-main {
  grid-area: feed;
  min-width: 0;
}

.report-feed-heading,
.reporter-panel-head,
.report-card-context,
.report-day-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.report-feed-heading {
  align-items: flex-end;
  margin-bottom: 18px;
}

.report-feed-heading h2,
.reporter-panel h2 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -.02em;
}

.report-feed-heading p,
.reporter-panel-head span {
  margin: 4px 0 0;
  color: var(--text-3);
  font-size: 12px;
}

.report-feed-order {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-2);
  font-size: 12px;
  white-space: nowrap;
}

.reporter-panel {
  position: sticky;
  top: 28px;
  grid-area: reporters;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.reporter-panel-head {
  align-items: flex-start;
  margin-bottom: 10px;
}

.reporter-panel-head span {
  margin: 2px 0 0;
}

.reporter-filter {
  display: flex;
  width: 100%;
  min-height: 50px;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border: 1px solid transparent;
  border-radius: 4px;
  background: transparent;
  color: var(--text-2);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 140ms var(--ease-out), border-color 140ms var(--ease-out), color 140ms var(--ease-out), transform 120ms var(--ease-out);
}

.reporter-filter + .reporter-filter {
  margin-top: 2px;
}

.reporter-filter.on {
  border-color: var(--border);
  background: var(--surface-2);
  color: var(--text);
  box-shadow: inset 0 -1px 0 var(--datum);
}

.reporter-filter:active {
  transform: scale(.97);
}

.reporter-filter:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.reporter-filter strong,
.reporter-filter small {
  display: block;
}

.reporter-filter strong {
  overflow: hidden;
  color: inherit;
  font-size: 13px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reporter-filter small {
  margin-top: 2px;
  color: var(--text-3);
  font-size: 11px;
}

.reporter-filter-avatar,
.reporter-filter-icon {
  display: grid;
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--canvas);
  color: var(--text-2);
  font-size: 10px;
  font-weight: 700;
}

.reporter-bonus-disclosure {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.reporter-bonus-disclosure summary {
  color: var(--text-2);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.reporter-bonus-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 10px;
  color: var(--text-2);
  font-size: 12px;
}

.report-day + .report-day {
  margin-top: 30px;
}

.report-day-heading {
  margin-bottom: 10px;
}

.report-day-heading h3 {
  margin: 0;
  color: var(--text-2);
  font-size: 13px;
  font-weight: 600;
}

.report-day-heading span {
  color: var(--text-3);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.report-feed-card {
  display: grid;
  grid-template-columns: minmax(270px, .86fr) minmax(360px, 1.14fr);
  min-height: 270px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.report-feed-card + .report-feed-card {
  margin-top: 12px;
}

.report-feed-card.is-dismissed {
  opacity: .68;
}

.report-feed-card-copy {
  display: flex;
  min-width: 0;
  flex-direction: column;
  padding: 18px;
  border-right: 1px solid var(--border);
}

.report-card-context {
  justify-content: flex-start;
}

.report-card-context strong,
.report-card-context small {
  display: block;
}

.report-card-context strong {
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
}

.report-card-context small {
  margin-top: 1px;
  color: var(--text-3);
  font-size: 11px;
}

.report-feed-card-copy > h3 {
  margin: 18px 0 0;
  color: var(--text);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -.02em;
}

.report-card-time {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
  margin-top: 5px;
  color: var(--text-3);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.report-feed-card-copy > p {
  display: -webkit-box;
  max-width: 58ch;
  margin: 13px 0 18px;
  overflow: hidden;
  color: var(--text-2);
  font-size: 13px;
  line-height: 1.5;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

.report-open {
  align-self: flex-start;
  margin-top: auto;
}

.report-media {
  display: grid;
  min-width: 0;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  background: var(--canvas);
}

.report-media-cell {
  position: relative;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  border-right: 1px solid var(--surface);
  border-bottom: 1px solid var(--surface);
  background: var(--surface-2);
}

.report-media-1 .report-media-cell {
  grid-column: 1 / -1;
  grid-row: 1 / -1;
}

.report-media-2 .report-media-cell {
  grid-row: 1 / -1;
}

.report-media-2 .report-media-cell:first-child {
  grid-column: 1 / 3;
}

.report-media-empty {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 8px;
  color: var(--text-3);
  font-size: 12px;
}

/* Reports inside one project: content first, plan controls disclosed below. */
.project-report-filter {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 12px;
}

.project-report-filter label {
  display: inline-flex;
  min-height: 40px;
  align-items: center;
  gap: 7px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text-2);
  font-size: 12px;
}

.project-report-filter select {
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-weight: 600;
}

.project-report-feed {
  display: grid;
  gap: 12px;
}

details.rep.project-report-card {
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

details.rep.project-report-card + details.rep.project-report-card {
  border-top: 1px solid var(--border);
}

details.rep.project-report-card summary {
  min-height: 68px;
  padding: 14px 16px;
}

details.rep.project-report-card .rep-body {
  padding: 0 16px 18px;
}

.project-report-media {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 4px;
  margin-top: 14px;
}

.project-report-media-cell {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 4px;
  background: var(--surface-2);
}

.report-support {
  margin-top: 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}

.report-support > summary {
  display: flex;
  min-height: 50px;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.report-support > summary span {
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

.report-support-body {
  padding: 0 16px 16px;
}

.report-support .rp-wrap {
  margin: 0;
  padding: 0;
  border: 0;
}

/* Dashboard project bars. One job per full-width row, read left to right: the
   property's own photo, who the job is, how big it is, then a strip of its
   recent field media running toward the right edge, then the way in.
   Deliberately a STACK, not a card grid: a job list is scanned down a single
   column of names, and a photo strip only reads as a strip when it has the
   page's whole width to run along. */
.dash-project-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.dash-project-row {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

/* The cover. A fixed square at the head of the bar, so ten jobs read as one
   column of names beside one column of faces — a hero sized by its own photo's
   aspect ratio would ragged that edge.
   140px, not the 60 it started at: at thumbnail size the photos were proof a
   job had photos, not something you could actually read a room off. This is
   the whole point of the row, so it gets the height. Keep this and
   .dash-project-media on the same number — they set the two edges the bar is
   read across. */
.dash-project-hero {
  position: relative;
  overflow: hidden;
  width: 140px;
  height: 140px;
  flex: 0 0 140px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
}

.dash-project-hero > .dash-project-media {
  position: absolute;
  width: auto;
  flex: none;
  border-radius: 0;
  inset: 0;
}

.dash-project-heroblank {
  display: grid;
  height: 100%;
  place-content: center;
  color: var(--text-3);
}

/* The frame holds the strip and the two arrows that step it. It is the
   positioning parent for those arrows, which is why the strip cannot be the
   card's direct child: they must sit still while the strip scrolls under them.
   It takes whatever the bar has left over and no more, so every row's photos
   end at the same x — the edge that makes a list of strips scan as one strip. */
.dash-project-frame {
  position: relative;
  min-width: 0;
  /* Two tiles plus their gap. Below that the strip is a single photo with a
     scrollbar's worth of promise, which is when the 900px fold is the better
     answer. */
  flex: 1 1 288px;
}

.dash-project-copy {
  display: flex;
  min-width: 0;
  /* Grows first, gives up last: the name is the one thing in the bar that
     cannot be recovered by looking harder at a photo. */
  flex: 1 1 190px;
  flex-direction: column;
  gap: 2px;
}

/* No truncation anywhere in the caption: a card that ends in an ellipsis has
   failed at its only job, which is telling the reader which job it is. Titles
   and addresses wrap, and every card in a row stays the same height because
   the copy is a flex child with the link pinned to its bottom. */
.dash-project-titleline h3 {
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 1.3;
}

.dash-project-copy > p {
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--text-2);
  font-size: 12px;
  line-height: 1.4;
}

.dash-project-meta {
  margin-top: 2px;
  color: var(--text-3);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.dash-project-meta strong {
  color: var(--text-2);
}

/* Counts. Numeral over noun so the eye can run down the list comparing sizes
   without re-reading the word on every row. */
.dash-project-stats {
  display: flex;
  flex: 0 0 auto;
  gap: 22px;
}

.dash-project-stat {
  display: flex;
  min-width: 46px;
  flex-direction: column;
  gap: 1px;
}

.dash-project-stat strong {
  color: var(--text);
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.dash-project-stat span {
  color: var(--text-3);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.dash-project-open {
  flex: 0 0 auto;
  margin-top: 0;
  padding-top: 0;
}

/* Several photos at once, running off the right edge — the shape that says
   "there are more of these" without a control saying it. Snapping is PROXIMITY,
   not mandatory: with a strip this wide the reader is allowed to rest between
   two tiles, and mandatory would yank the strip back after every flick, which
   reads as the list arguing. The scrollbar is hidden because it would cut
   across the bottom of the photos; the arrows and the photo count are the
   affordance. */
.dash-project-gallery {
  display: flex;
  min-width: 0;
  gap: 8px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.dash-project-gallery::-webkit-scrollbar {
  display: none;
}

.dash-project-media {
  position: relative;
  overflow: hidden;
  width: 140px;
  flex: 0 0 140px;
  aspect-ratio: 1 / 1;
  border-radius: 8px;
  background: var(--surface-2);
  scroll-snap-align: start;
}

.dash-project-media > img,
.dash-project-media > video {
  position: relative;
  z-index: 1;
  opacity: 0;
  transition: opacity 160ms var(--ease-out);
}

.dash-project-media.is-ready > img,
.dash-project-media.is-ready > video {
  opacity: 1;
}

/* Same height as a tile, so a photo-less job keeps the bar the same height as
   every other bar instead of collapsing out of the rhythm. Inline rather than a
   square: there is no photo to frame, and an empty 140px box pretending to be
   one is a promise the row cannot keep. */
.dash-project-empty {
  display: flex;
  height: 140px;
  align-items: center;
  gap: 8px;
  color: var(--text-3);
  font-size: 12px;
}

.dash-project-more {
  justify-content: center;
  min-height: 46px;
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
}

@media (hover: hover) and (pointer: fine) {
  .project-feed-card:hover,
  .report-feed-card:hover,
  .dash-project-row:hover {
    border-color: var(--border-strong);
    box-shadow: var(--shadow-hover);
  }

  .reporter-filter:hover {
    background: var(--surface-2);
    color: var(--text);
  }

  .project-feed-media-cell:hover img,
  .project-feed-media-cell:hover video,
  .report-media-cell:hover img,
  .report-media-cell:hover video {
    transform: scale(1.02);
  }
}

/* The bar folds rather than crushes. Below this the strip can no longer show a
   meaningful number of photos while the name still has room to be a name, so it
   drops to its own full-width line underneath — still a strip, still horizontal,
   just with the whole row to itself. */
@media (max-width: 900px) {
  .dash-project-row {
    flex-wrap: wrap;
    row-gap: 10px;
  }

  .dash-project-open {
    order: 4;
    margin-left: auto;
  }

  .dash-project-frame {
    order: 5;
    flex: 1 1 100%;
  }
}

@media (max-width: 560px) {
  .dash-project-stats {
    gap: 14px;
  }

  .dash-project-copy {
    flex-basis: 100%;
  }
}

@media (max-width: 1040px) {
  .project-feed-card,
  .report-feed-card {
    grid-template-columns: minmax(250px, .82fr) minmax(340px, 1.18fr);
  }

  .report-workspace {
    grid-template-columns: minmax(0, 1fr) 240px;
    gap: 16px;
  }
}

@media (max-width: 820px) {
  .project-feed-card,
  .report-feed-card {
    grid-template-columns: minmax(0, 1fr);
  }

  .project-feed-copy,
  .report-feed-card-copy {
    border-right: 0;
    border-bottom: 1px solid var(--border);
  }

  .project-feed-media,
  .report-media {
    min-height: 220px;
  }

  .report-workspace {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: 'reporters' 'feed';
  }

  .reporter-panel {
    position: static;
  }

  #reporter-filters {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding-bottom: 4px;
  }

  .reporter-filter {
    width: 210px;
    flex: 0 0 210px;
  }

  .reporter-filter + .reporter-filter {
    margin-top: 0;
  }
}

@media (max-width: 600px) {
  .dash-page-h {
    flex-direction: column;
    align-items: flex-start !important;
  }

  .dash-page-h h1 {
    max-width: none;
  }

  .dash-actions {
    width: 100%;
  }

  .dash-actions .btn {
    flex: 1 1 0;
    justify-content: center;
  }

  .project-feed-toolbar,
  .project-feed-filters,
  .project-feed-actions,
  .report-feed-toolbar {
    align-items: stretch;
  }

  .project-feed-filters,
  .project-feed-actions,
  .project-feed-actions .search,
  .report-feed-search,
  .report-feed-toolbar .wsel {
    width: 100%;
  }

  .project-feed-actions .btn {
    flex: 1 1 auto;
  }

  #pj-chips {
    width: 100%;
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 4px;
  }

  #pj-chips .chip {
    min-height: 42px;
    flex: 0 0 auto;
  }

  .project-feed-copy,
  .report-feed-card-copy {
    padding: 17px;
  }

  .project-feed-media {
    display: flex;
    min-height: 0;
    overflow-x: auto;
    padding: 4px;
    gap: 4px;
    scroll-snap-type: x proximity;
  }

  .project-feed-media-cell {
    width: 170px;
    height: 132px;
    flex: 0 0 170px;
    border: 0;
    border-radius: 4px;
    scroll-snap-align: start;
  }

  .project-feed-empty-media {
    width: 100%;
    min-height: 132px;
  }

  .report-feed-heading {
    align-items: flex-start;
  }

  .report-feed-order {
    display: none;
  }

  .report-media {
    min-height: 190px;
  }

  .project-report-media {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .project-report-filter,
  .project-report-filter label {
    width: 100%;
  }

  .project-report-filter select {
    flex: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  #screen-dashboard .photo-strip .ps-cell img,
  #screen-dashboard .photo-strip .ps-cell video,
  #screen-dashboard .li-row,
  .btn,
  .chip,
  .side-item,
  .theme-option {
    transition-duration: .01ms !important;
  }

  .project-feed-card,
  .reporter-filter,
  .project-feed-media-cell img,
  .project-feed-media-cell video,
  .report-media-cell img,
  .report-media-cell video,
  .dash-project-media > img,
  .dash-project-media > video {
    transition-duration: .01ms !important;
  }
}

/* Estimate proposal parity (contractor iOS build 2356). */
.side-theme {
  margin: 10px 0 0;
  padding: 12px 8px 2px;
  border-top: 1px solid var(--border);
}
.side-theme-label {
  display: block;
  margin-bottom: 7px;
  color: var(--text-3);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.side-theme-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  background: var(--canvas);
}
.side-theme-options button {
  min-height: 30px;
  border: 1px solid transparent;
  border-radius: 3px;
  background: transparent;
  color: var(--text-2);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.side-theme-options button.on {
  border-color: var(--border-strong);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--hairline-up);
}
body.side-collapsed .side-theme { display: none; }

/* ── Document split: editor left, live PDF preview right ──────────────────
   Used by the Scope and Estimates tabs (screens/doc-preview.js). Two jobs:
   keep the editor column at a readable measure (~12 words a line) instead of
   letting a description box run the full 1320px, and put the width that frees
   up toward a preview of the document being sent. Below WIDE_AT the pane is
   removed in JS and the single column simply centres. */
.docsplit-main {
  max-width: 74ch;
  margin-inline: auto;
}
/* Row-1 chrome. Two slots: `.docsplit-chrome` over the editor column (the
   owning screen's own controls, e.g. the estimate's presentation/export row)
   and `.docsplit-rail` over the page column, which carries the preview label,
   the zoom readout and the Hide-preview toggle. The toggle lives with the
   thing it controls — over the editor it read as a control for the editor.
   Off the split both track the editor's 74ch measure so they sit over the
   card they belong to. */
.docsplit-chrome {
  max-width: 74ch;
  margin: 0 auto 10px;
}
.docsplit-rail {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  max-width: 74ch;
  margin: 0 auto 10px;
}
.docsplit-bar {
  display: flex;
  justify-content: flex-end;
}
/* 74ch is the top of the 9–15 word band the editor should sit in; the pane's
   520px floor stops a long measure from starving the preview into a thumbnail.
   Past ~1150px the editor caps out and every extra pixel goes to the page.

   Two explicit rows, not an auto flow: row 1 is the chrome — the owning
   screen's controls over the editor, and the "…PDF preview · 100%" label plus
   the Hide-preview toggle over the page — row 2 is the two documents. Placing them by hand is what makes the top
   of the editor card and the top of the page box land on one shared y-line —
   left to itself the label rode inside the pane and pushed the page down by its
   own height, so two columns of the same estimate started at two different
   heights. */
.docsplit.on {
  display: grid;
  grid-template-columns: minmax(0, 74ch) minmax(520px, 1fr);
  grid-template-rows: auto auto;
  column-gap: 28px;
  row-gap: 10px;
  align-items: start;
}
.docsplit.on .docsplit-chrome {
  grid-column: 1;
  grid-row: 1;
  max-width: none;
  margin: 0;
  align-self: center;
}
.docsplit.on .docsplit-rail {
  grid-column: 2;
  grid-row: 1;
  max-width: none;
  margin: 0;
  justify-content: space-between;
  align-self: center;
}
.docsplit.on .docsplit-main { grid-column: 1; grid-row: 2; margin-inline: 0; }
.docsplit.on .docsplit-pane { grid-column: 2; grid-row: 2; }
.docsplit-pane {
  position: sticky;
  top: 24px;
  min-width: 0;
}
.docsplit-head {
  display: flex;
  flex: 1;
  min-width: 0;
  align-items: baseline;
  gap: 12px;
  color: var(--text-3);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
}
/* display:flex above outranks the hidden attribute's UA display:none, and both
   are toggled by that attribute — the label when the pane is dismissed, the
   rail when the viewport is too narrow to offer the split at all. */
.docsplit-head[hidden] { display: none; }
.docsplit-rail[hidden] { display: none; }
.docsplit-zoom {
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
}
.docsplit-scroll {
  max-height: calc(100vh - 150px);
  overflow: auto;
  padding: 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--canvas);
  box-shadow: var(--hairline-up);
}
.docsplit-stage {
  position: relative;
  margin-inline: auto;
}
.docsplit-frame {
  display: block;
  transform-origin: 0 0;
  border: 0;
  background: #fff;
  border-radius: 3px;
  box-shadow: 0 18px 40px -24px rgba(0, 0, 0, .6);
}
.docsplit-status {
  padding: 28px 16px;
  color: var(--text-3);
  font-size: 13px;
  text-align: center;
}
.docsplit-status.err { color: var(--text-2); }

@media (max-width: 899px) {
  .docsplit.on { grid-template-columns: minmax(0, 1fr); }
  .docsplit.on .docsplit-chrome,
  .docsplit.on .docsplit-rail,
  .docsplit.on .docsplit-main { grid-column: 1; }
  .docsplit.on .docsplit-head,
  .docsplit.on .docsplit-pane { display: none; }
}

/* Estimates tab header. Total stacked over its controls, both full width above
   the split — see renderEstimate() for why it can't live inside the editor
   column. Left-aligned rather than pushed to the far right: read top to bottom
   it's the number, then the settings that produced it, then the sheet. */
.fx-est-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 18px;
}
.fx-est-controls { justify-content: flex-start; }

body:has(.docsplit.on) .content {
  max-width: 1660px;
}

body:has(#screen-estimate-editor.on) .content {
  max-width: 1660px;
}
#screen-estimate-editor .ee-workbench {
  grid-template-columns: minmax(610px, 1fr) minmax(600px, 720px);
  gap: 24px;
}
#screen-estimate-editor .ee-preview-pane { min-width: 600px; }
#screen-estimate-editor #ee-preview {
  max-height: calc(100vh - 154px);
  overflow: auto;
  border-radius: var(--radius);
  background: var(--canvas);
}
/* The bespoke `.ee-document` page box is gone: both previews now render
   estimateDocHtml() inside a sandboxed srcdoc iframe (.docsplit-frame), which
   paints its own page. Styles here could never reach into that document. */
#screen-estimate-editor .ee-room-head {
  background: color-mix(in srgb, var(--surface-2) 76%, var(--text) 6%);
  border-bottom-color: var(--border-strong);
}
#screen-estimate-editor .ee-room-card {
  border-color: var(--border-strong);
}
#screen-estimate-editor .ee-control,
#screen-estimate-editor .ee-in,
#screen-estimate-editor .ee-preview-head select {
  border-color: color-mix(in srgb, var(--text) 34%, var(--border-strong));
}
#screen-estimate-editor .ee-control:focus,
#screen-estimate-editor .ee-in:focus,
#screen-estimate-editor .ee-preview-head select:focus {
  border-color: var(--datum);
  box-shadow: var(--ring);
}

/* Document presentation controls (work-editor.js), mounted on BOTH estimate
   routes. pro-dev.html only styles these selects as `.ee-preview-head select`,
   so on the project tab's Estimates header — where the shared helper now puts
   them — they would render as raw UA dropdowns. Same values, restated without
   the `.ee-preview-head` ancestor; the head's own (higher-specificity) rules
   still own layout and border colour inside the estimate editor. */
.ee-preview-controls {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.ee-preview-controls select {
  max-width: 210px;
  min-height: 36px;
  padding: 7px 28px 7px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.ee-preview-controls select:focus {
  outline: none;
  border-color: var(--datum);
  box-shadow: var(--ring);
}
#screen-estimate-editor .ee-money-input {
  border: 1px solid color-mix(in srgb, var(--text) 34%, var(--border-strong));
}
#screen-estimate-editor .ee-money-input:focus-within {
  position: relative;
  z-index: 2;
  border-color: var(--datum);
  box-shadow: var(--ring);
}
#screen-estimate-editor .ee-money-input .ee-control:focus { box-shadow: none; }
/* Segmented control. The selected segment MUST read as filled — this used to
   repaint it `surface-2` with `--text`, which on a light card is the same wash
   as the unselected segments, so the control silently stopped saying which
   mode was on. Only the UNSELECTED segments get the tightened instrument
   border now; the checked one keeps the base graphite fill and just lifts a
   layer so its border wins over the neighbour it shares an edge with. */
#screen-estimate-editor .ee-material-mode input:not(:checked) + span {
  border-color: color-mix(in srgb, var(--text) 34%, var(--border-strong));
}
#screen-estimate-editor .ee-material-mode input:checked + span {
  position: relative;
  z-index: 1;
}
/* Focus is on the visually-hidden input, so the ring has to be drawn on the
   label. Above the checked segment's z-index, or a focused-but-unselected
   segment loses its ring under the filled neighbour. */
#screen-estimate-editor .ee-material-mode input:focus-visible + span {
  position: relative;
  z-index: 2;
  outline: none;
  box-shadow: var(--ring);
}
.ee-menu-rule { height: 1px; margin: 5px 4px; background: var(--border); }
.ee-menu-primary { font-weight: 650; }
.ee-menu-primary svg { color: var(--accent); }

.ee-photo-viewer {
  position: fixed;
  inset: 0;
  z-index: 1300;
  display: grid;
  place-items: center;
  padding: 28px;
  background: rgba(5,8,10,.88);
}
.ee-photo-dialog {
  position: relative;
  width: min(1040px, 94vw);
  height: min(820px, 90vh);
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) 52px;
  grid-template-rows: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
}
.ee-photo-stage {
  grid-column: 2;
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: contain;
}
.ee-photo-prev, .ee-photo-next, .ee-photo-close {
  width: 44px;
  height: 44px;
  border: 1px solid rgba(255,255,255,.28);
  border-radius: 4px;
  background: rgba(20,24,26,.78);
  color: #fff;
  font: inherit;
  font-size: 30px;
  cursor: pointer;
}
.ee-photo-prev { grid-column: 1; grid-row: 1; }
.ee-photo-next { grid-column: 3; grid-row: 1; }
.ee-photo-close { position: absolute; top: 0; right: 0; z-index: 2; font-size: 24px; }
.ee-photo-count { grid-column: 2; color: #fff; text-align: center; font-size: 13px; }
.ee-photo-rail { grid-column: 1 / -1; display: flex; justify-content: center; gap: 6px; overflow-x: auto; }
.ee-photo-rail button { width: 58px; height: 46px; flex: 0 0 auto; padding: 0; border: 2px solid transparent; border-radius: 4px; overflow: hidden; opacity: .55; background: none; cursor: pointer; }
.ee-photo-rail button.on { border-color: #fff; opacity: 1; }
.ee-photo-rail img { width: 100%; height: 100%; display: block; object-fit: cover; }

/* Fully visible track, thumb, and focus state in both color themes. */
.switch { width: 44px !important; height: 26px !important; }
.switch .sw-knob {
  border: 1px solid var(--border-strong);
  border-radius: 13px !important;
  background: var(--surface-2);
}
.switch .sw-knob::after {
  top: 2px !important;
  left: 2px !important;
  width: 20px !important;
  height: 20px !important;
  border: 1px solid var(--border-strong) !important;
  background: var(--text) !important;
  box-shadow: none !important;
}
.switch input:checked + .sw-knob { border-color: var(--orange); background: var(--orange); }
.switch input:checked + .sw-knob::after { transform: translateX(18px) !important; background: #fff !important; }

.ee-savebar[hidden] { display: none !important; }
.ee-line-toggle-hint { display: inline-flex; align-items: center; gap: 7px; color: var(--text-3); }
.ee-line-toggle-hint > small { font-size: 11px; font-weight: 600; }
.ee-line-toggle-hint .ee-line-chev {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-2);
}
.ee-line-card.expanded .ee-line-toggle-hint .ee-line-chev { transform: rotate(90deg); }
.ee-drawer-actions { justify-content: space-between; }

/* Drawer chrome: collapse carets top + bottom (close without saving) and the
   Save line / Cancel button row. */
.ee-drawer-caret {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
  transition: transform 200ms cubic-bezier(0.23, 1, 0.32, 1);
}
.ee-drawer-caret svg { transform: rotate(-90deg); transition: transform 200ms cubic-bezier(0.23, 1, 0.32, 1); }
.ee-drawer-caret:hover { color: var(--text); }
.ee-drawer-caret:active { transform: scale(0.97); }
.ee-drawer-actions.ee-drawer-actions-bottom { justify-content: center; margin-top: 8px; }
.ee-drawer-buttons { align-items: center; gap: 8px; }
.ee-drawer-buttons-right { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.ee-drawer-buttons .btn { min-height: 34px; }
.ee-confirm-line { gap: 6px; }

/* Notes | photos share the drawer row when the drawer itself is wide enough
   for two comfortable columns, stack when narrow. Container query, not
   viewport: with the PDF preview docked the editor pane can be half the
   viewport, so viewport width lies about the space we actually have. */
.ee-line-drawer { container-type: inline-size; }
.ee-drawer-split { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px 16px; align-items: start; }
@container (min-width: 700px) {
  .ee-drawer-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* Collapsed-row staged-edit diffs: struck-through old value → new, plus a
   dot badge on any edited-but-unsaved row (REN-593 parity). */
.ee-line-old-task { display: block; color: var(--text-3); font-size: 11px; font-weight: 400; }
.ee-old-val { color: var(--text-3); font-weight: 400; }
.ee-diff-to { margin: 0 4px; color: var(--text-3); font-weight: 400; }
.ee-edit-dot {
  width: 7px;
  height: 7px;
  display: inline-block;
  margin-left: 6px;
  border-radius: 50%;
  background: var(--orange);
  vertical-align: middle;
}

/* Photo strip drag-to-reorder: dragged thumb dims, a 2px accent bar marks
   the insertion point. */
.ee-attach-thumb { transition: opacity 180ms cubic-bezier(0.23, 1, 0.32, 1), transform 180ms cubic-bezier(0.23, 1, 0.32, 1); }
.ee-attach-thumb.ee-photo-dragging { opacity: 0.35; }
.ee-attach-thumb.ee-drop-before::before,
.ee-attach-thumb.ee-drop-after::after {
  content: "";
  position: absolute;
  top: 2px;
  bottom: 2px;
  width: 2px;
  border-radius: 1px;
  background: var(--datum);
}
.ee-attach-thumb.ee-drop-before::before { left: -5px; }
.ee-attach-thumb.ee-drop-after::after { right: -5px; }

/* "From project photos" inline expanding panel (0fr→1fr, no modal). */
.ee-photo-picker {
  flex-basis: 100%;
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 220ms cubic-bezier(0.23, 1, 0.32, 1);
}
.ee-photo-picker.open { grid-template-rows: 1fr; }
.ee-photo-picker-clip { overflow: hidden; min-height: 0; }
.ee-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
  gap: 6px;
  padding: 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--canvas);
}
.ee-picker-thumb {
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
  overflow: hidden;
  transition: transform 150ms cubic-bezier(0.23, 1, 0.32, 1);
}
.ee-picker-thumb:active { transform: scale(0.97); }
.ee-picker-thumb img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; }
.ee-picker-note { padding: 8px 2px; color: var(--text-3); }

@media (prefers-reduced-motion: reduce) {
  .ee-drawer-caret,
  .ee-drawer-caret svg,
  .ee-attach-thumb,
  .ee-photo-picker,
  .ee-picker-thumb { transition: none; }
}

.ee-provider-toggle {
  width: 132px;
  flex: 0 0 132px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
}
.ee-provider-toggle > small { color: var(--text-3); font-size: 11px; line-height: 1.2; }
#screen-estimate-editor .ee-material-options { grid-template-columns: minmax(280px, 430px); }

@media (max-width: 1560px) {
  #screen-estimate-editor .ee-workbench { grid-template-columns: minmax(0, 1fr); }
  #screen-estimate-editor .ee-preview-pane { min-width: 0; }
  #screen-estimate-editor #ee-preview { max-height: none; }
}
@media (max-width: 899px) {
  .side-theme { display: none; }
}
@media (max-width: 600px) {
  .ee-photo-viewer { padding: 14px; }
  .ee-photo-dialog { width: 100%; height: 88vh; grid-template-columns: 40px minmax(0, 1fr) 40px; }
  .ee-photo-prev, .ee-photo-next { width: 38px; height: 38px; }
}

/* ── Scope inline line editor ── */
/* iOS-style staged editing on the Scope tab: rows expand in place (grid-rows
   0fr→1fr), edits stage with strikethrough old→new previews, and a sticky
   orange save bar commits everything at once. */

.sle-card { position: relative; }

/* Rooms */
.sle-room { border-top: 1px solid var(--border); }
.sle-room:first-child { border-top: 0; }
.sle-room-head {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0; cursor: pointer; font-weight: 600; list-style: none;
}
.sle-room-head::-webkit-details-marker { display: none; }
.sle-room-head::before {
  content: ''; flex: 0 0 auto; width: 0; height: 0;
  border-left: 5px solid var(--text-3);
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform 0.18s var(--ease-out);
}
.sle-room[open] > .sle-room-head::before { transform: rotate(90deg); }
.sle-rname { min-width: 0; overflow-wrap: anywhere; }
/* Hover affordances on this surface are gated behind a real pointer. On touch,
   `:hover` latches after a tap and leaves the row stuck in its hover paint until
   something else is tapped. `:active` and `:focus-visible` stay ungated — they
   are the feedback that touch and keyboard actually rely on. */
@media (hover: hover) and (pointer: fine) {
  .sle-rname:hover { text-decoration: underline dotted var(--text-3); text-underline-offset: 3px; }
}
.sle-rname:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--radius-sm); }
.sle-rname-input { width: min(240px, 60vw); font: inherit; }
.sle-room-n { font-weight: 400; flex: 0 0 auto; }
/* The room total is what gets pushed to the right edge when it exists, with
   the trash button trailing it; on a Scope room (no total) or a deleted room
   (total suppressed) the button takes the push instead. Flexbox SPLITS free
   space between every auto margin, so the trailing one has to be cancelled
   explicitly or the total floats mid-header. */
.sle-room-head .sle-room-total,
.sle-room-head .sle-iconbtn, .sle-room-head .sle-room-undo { margin-left: auto; }
.sle-room-head .sle-room-total ~ .sle-iconbtn,
.sle-room-head .sle-room-total ~ .sle-room-undo { margin-left: 0; }

/* Room total + its proportional stepper. Same engine as the estimate grand
   total: −/+ retarget the room, and every priced line inside it moves with it.
   Sized below the 36px `.ee-step-control > button` default — this rides inside
   a 32px-tall room header, not a form field. */
.sle-room-head .sle-room-total { width: auto; flex: 0 0 auto; gap: 2px; }
.sle-room-total .sle-room-step {
  width: 28px; height: 28px; flex-shrink: 0; padding: 0;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text);
  font: inherit; font-size: 15px; line-height: 1; cursor: pointer;
  transition: background 0.12s var(--ease-out), border-color 0.12s var(--ease-out), transform 0.12s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .sle-room-total .sle-room-step:hover:not(:disabled) { background: var(--surface-2); border-color: var(--text-3); }
}
/* Instant. The press is the feedback; a transition on the NUMBER would smear
   held-down repeats into an unreadable blur. */
.sle-room-total .sle-room-step:active:not(:disabled) { transform: scale(0.97); }
.sle-room-total .sle-room-step:focus-visible { outline: none; box-shadow: var(--ring); }
.sle-room-total .sle-room-step:disabled { opacity: 0.45; cursor: default; }
.sle-room-sum {
  min-width: 72px; padding: 0 4px; text-align: center;
  font-variant-numeric: tabular-nums; transition: none;
}
.sle-room-del { opacity: 0.65; }
.sle-room-del .sle-rname { text-decoration: line-through; color: var(--text-3); }
@media (hover: hover) and (pointer: fine) {
  .sle-room-del .sle-rname:hover { text-decoration: line-through; }
}
.sle-room-del .sle-lines, .sle-room-del .sle-addline { display: none; }

/* Small ghost icon button (trash, collapse caret) */
.sle-iconbtn {
  display: grid; place-items: center; width: 32px; height: 32px; padding: 0;
  border: 0; border-radius: var(--radius-sm); background: none;
  color: var(--text-3); cursor: pointer;
  transition: background 0.12s var(--ease-out), color 0.12s var(--ease-out), transform 0.12s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .sle-iconbtn:hover { color: var(--text); background: var(--surface-2); }
}
.sle-iconbtn:active { transform: scale(0.97); }
.sle-iconbtn:focus-visible { outline: none; box-shadow: var(--ring); }

/* Line rows */
.sle-lines { list-style: none; margin: 0; padding: 0; }
.sle-item { border-top: 1px solid var(--border); }
/* Columns: content | [thumbs] | [price] | caret — or content | undo on a deleted
   row. Only the content track is declared; the rest are implicit, created one per
   child that is actually emitted. Declaring four fixed tracks was wrong: an unused
   `auto` track collapses to zero WIDTH but the 12px `gap` on either side of it
   still renders, so the caret sat 12px (three children) or 24px (two children)
   short of the right edge. */
.sle-rowline {
  display: grid; grid-auto-flow: column;
  grid-template-columns: minmax(0, 1fr); grid-auto-columns: auto;
  gap: 12px; align-items: center;
  padding: 14px 6px; cursor: pointer; border-radius: var(--radius-sm);
  transition: background 0.12s var(--ease-out), transform 0.12s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .sle-rowline:hover { background: var(--surface); }
  /* Higher specificity than the rule above, so this stays a no-op override
     regardless of where the gate puts it in source order. */
  .sle-deleted .sle-rowline:hover { background: none; }
}
.sle-rowline:active { transform: scale(0.99); }
.sle-rowline:focus-visible { outline: none; box-shadow: var(--ring); }
.sle-deleted .sle-rowline { cursor: default; }
.sle-deleted .sle-rowline:active { transform: none; }
.sle-row-main { min-width: 0; }
.sle-task { font-weight: 600; font-size: 14px; }
.sle-task-ph { color: var(--text-3); font-weight: 500; }
.sle-meas { font-weight: 400; }
.sle-meas-old, .sle-old-inline { color: var(--text-3); }
.sle-old {
  display: block; font-size: 12px; color: var(--text-3);
  text-decoration: line-through; margin-bottom: 1px;
}
.sle-notes {
  margin-top: 3px; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.sle-struck { text-decoration: line-through; color: var(--text-3); }
.sle-dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--orange); vertical-align: 2px; margin-left: 3px;
}

/* Collapsed-row photo thumbs */
.sle-row-thumbs { display: flex; gap: 6px; }
.sle-mini {
  width: 96px; height: 70px; border-radius: 8px; overflow: hidden;
  border: 1px solid var(--border); background: var(--surface);
}
.sle-mini img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sle-mini-more { display: grid; place-items: center; font-size: 12px; font-weight: 600; color: var(--text-2); }

/* Line price (estimate mode) — the headline number on a collapsed row. */
.sle-price {
  text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: 15px;
}
.sle-price-old { color: var(--text-3); font-weight: 500; font-size: 13px; }
.sle-price-unset { color: var(--text-3); font-weight: 500; font-size: 13px; }
.sle-price-hint { color: var(--text-3); margin-top: 4px; }

/* Materials (estimate mode) */
/* Three modes: None / Some / All. "Some" is the stored `selected` mode — the
   per-material supplier picker below is what drives it. */
.sle-mats .ee-material-mode { grid-template-columns: repeat(3, minmax(0, 1fr)); max-width: 330px; margin-bottom: 6px; }
.sle-mat-hint { color: var(--text-3); margin-bottom: 8px; }
.sle-mat-hint[hidden] { display: none; }
.sle-mat-empty { padding: 10px 6px; color: var(--text-3); border-top: 1px solid var(--border); }

/* Per-material supplier picker, only rendered in "Some" mode. It sits inside
   the collapsed row, whose own click opens the drawer — the pointer cursor is
   the row's, so restate it here rather than inheriting the row's affordance. */
.sle-rowline .ee-material-provider {
  min-height: 32px;
  padding: 5px 8px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-2);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.sle-rowline .ee-material-provider:focus-visible { outline: none; box-shadow: var(--ring); }
.sle-deleted .ee-material-provider { display: none; }

/* Expand caret */
.sle-caret { display: grid; place-items: center; color: var(--text-3); transition: transform 0.2s var(--ease-out); }
.sle-open .sle-caret { transform: rotate(180deg); }
.sle-collapse svg { transform: rotate(180deg); }

/* Drawer — grid-rows collapse trick; inner content fades/slides */
.sle-drawer { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.2s var(--ease-out); }
.sle-drawer-in { overflow: hidden; min-height: 0; }
.sle-open .sle-drawer { grid-template-rows: 1fr; }
.sle-form {
  display: flex; flex-direction: column; gap: 12px; padding: 4px 4px 14px;
  opacity: 0; transform: translateY(-4px);
  transition: opacity 0.18s var(--ease-out), transform 0.18s var(--ease-out);
}
.sle-open .sle-form { opacity: 1; transform: none; }
.sle-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
/* `display: flex` above outranks the UA's `[hidden] { display: none }` —
   without this guard the custom-unit field (and empty pool picker) render
   even when the JS sets `hidden`. */
.sle-field[hidden], .sle-pool[hidden] { display: none; }
.sle-summary-field { margin: 2px 0 10px; max-width: 760px; }
.sle-foot { display: flex; justify-content: space-between; align-items: center; }
.sle-delline { display: inline-flex; align-items: center; gap: 6px; color: var(--red); }
.sle-addline { margin: 2px 0 10px; }

/* Drawer photo strip */
.sle-photos {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: stretch;
  border-radius: var(--radius-sm);
  transition: background-color 0.15s var(--ease-out);
}
/* Cross-line photo drag: the hovered drop target (another line's photo strip
   or collapsed row) lights up so the move destination is unmistakable. */
.sle-photos.sle-drop, .sle-rowline.sle-drop {
  background-color: rgba(249, 115, 22, 0.08);
  outline: 2px dashed var(--orange); outline-offset: -2px;
}
.sle-ph {
  position: relative; width: 84px; height: 62px; border-radius: 6px;
  overflow: hidden; border: 1px solid var(--border); cursor: grab; flex: 0 0 auto;
}
.sle-ph img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
.sle-ph.sle-drag { opacity: 0.5; }
.sle-ph-x {
  position: absolute; top: 2px; right: 2px; width: 24px; height: 24px; padding: 0;
  display: grid; place-items: center; border: 0; border-radius: 50%;
  background: rgba(12, 15, 16, 0.72); color: #F8FAFA; font-size: 13px; line-height: 1;
  cursor: pointer; transition: transform 0.12s var(--ease-out);
}
.sle-ph-x:active { transform: scale(0.97); }
/* Negative offset draws the ring inside the button's own box. The parent
   `.sle-ph` is `overflow: hidden` with a 6px radius and this button sits 2px
   from its top/right edges, so an outward ring would be clipped at the corner. */
.sle-ph-x:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }
.sle-ph-add {
  min-width: 84px; min-height: 62px; padding: 0 10px;
  border: 1px dashed var(--border-strong); border-radius: 6px; background: none;
  color: var(--text-2); font-size: 12px; font-weight: 600; cursor: pointer;
  transition: color 0.12s var(--ease-out), border-color 0.12s var(--ease-out), transform 0.12s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .sle-ph-add:hover { color: var(--text); border-color: var(--text-3); }
}
.sle-ph-add:active { transform: scale(0.97); }
.sle-ph-add:focus-visible { outline: none; box-shadow: var(--ring); }
.sle-upstat:empty { display: none; }
.sle-upstat { margin-top: 6px; }

/* Pool picker (add from project photos) */
.sle-pool {
  display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; padding: 8px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
}
.sle-pool-cell {
  width: 72px; height: 54px; padding: 0; overflow: hidden; cursor: pointer;
  border: 1px solid var(--border); border-radius: 6px; background: none;
  transition: border-color 0.12s var(--ease-out), transform 0.12s var(--ease-out);
}
.sle-pool-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (hover: hover) and (pointer: fine) {
  .sle-pool-cell:hover { border-color: var(--border-strong); }
}
.sle-pool-cell:active { transform: scale(0.97); }
.sle-pool-cell:focus-visible { outline: none; box-shadow: var(--ring); }

/* Expand / collapse menu — anchored under a LEFT-aligned trigger, so the
   `.fx-menu-pop` default of `right: 0` (built for the right-edge Export menu)
   would hang the panel off the wrong side of its own button. */
.sle-viewmenu .fx-menu-pop { right: auto; left: 0; min-width: 190px; }
.sle-viewmenu-btn { white-space: nowrap; }
.sle-card-title { min-width: 0; flex-wrap: wrap; }

@media (prefers-reduced-motion: reduce) {
  .sle-room-head::before,
  .sle-iconbtn,
  .sle-room-total .sle-room-step,
  .sle-rowline,
  .sle-caret,
  .sle-drawer,
  .sle-form,
  .sle-ph,
  .sle-ph-x,
  .sle-ph-add,
  .sle-photos,
  .sle-pool-cell { transition: none; }
}

/* Sticky save bar */
.sle-savebar {
  position: sticky; bottom: 12px; z-index: 5;
  display: flex; justify-content: flex-end; align-items: center; gap: 10px;
  margin-top: 14px; padding: 10px 12px;
  background: var(--sheet); border: 1px solid var(--border-strong);
  border-radius: var(--radius); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
}
.sle-savebar[hidden] { display: none; }

/* With the PDF preview pane mounted the editor column is roughly half the
   content width, so collapsed-row thumbs need their narrow size even though the
   viewport is wide. Scoped to >=900px because below that the preview pane is
   hidden and the plain viewport breakpoints below own the sizing. */
@media (min-width: 900px) {
  .docsplit.on .sle-mini { width: 76px; height: 56px; }
}

@media (max-width: 900px) {
  .sle-mini { width: 76px; height: 56px; }
}
@media (max-width: 600px) {
  .sle-mini { width: 60px; height: 44px; border-radius: 6px; }
  .sle-rowline { gap: 8px; }
  .sle-savebar { bottom: 8px; }
}
