/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* Hide scrollbar while keeping scroll functionality */
.hide-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
.hide-scrollbar::-webkit-scrollbar { display: none; }

/* ============================================
   Custom Leaflet Map Styles — THE ONLY COPY.

   These rules live inline here, rather than in their own leaflet_custom.css,
   because Propshaft does not resolve @import between stylesheets: a separate
   file cannot be pulled in by one that a layout links. They were pasted here
   for that reason and the original file was left behind, so both shipped
   until B-404.

   🚩 The duplicate was not dead — it was WORSE than dead, and that is the part
   worth remembering. Most layouts name their stylesheets ("application",
   "tailwind"), so the copy never loaded there. But onboarding, public_form and
   new_design_application call `stylesheet_link_tag :app`, which is Propshaft's
   BULK option — every css file under app/assets — so the duplicate loaded on
   those three and nowhere else. An edit to it therefore changed nothing on the
   surface you were looking at and quietly changed three public-facing layouts
   you were not. The B-401/B-402 brief cited leaflet_custom.css:19-21 as the
   live source of the unlayered `.leaflet-popup-content strong` rule a DS card
   has to dodge; the rule that reaches the maps is the one below.

   Map CSS is edited HERE. Guard: spec/misc/stylesheet_duplication_spec.rb.
   ============================================ */

.property-marker {
  background: transparent !important;
  border: none !important;
}

.property-marker .fa-house {
  font-size: 12px;
}

/* Custom popup styling */
.leaflet-popup-content {
  margin: 8px 12px;
  font-size: 13px;
  line-height: 1.4;
}

.leaflet-popup-content strong {
  color: #1e40af;
}

/* 🚨 THE JOB MAP'S CARD OWNS ITS OWN FRAME, SO LEAFLET MUST STOP DRAWING ONE UNDER IT (B-401).
   `.score-map__card` is a design-system block — square, --border-default, --shadow-md — and
   Leaflet wraps every popup in `.leaflet-popup-content-wrapper`, which draws a 12px radius and a
   `0 3px 14px rgba(0,0,0,.4)` shadow of its own. Nested, the two read as a rounded grey halo
   around a square card.

   This is LIBRARY GLUE, not design-system grammar, which is why it lives here rather than in
   patterns.css: the DS declares what the card looks like, and the consumer stops its map library
   disagreeing. The DS specimen (preview/job_map.html) says the same thing from the other side.

   🚩 SCOPED TO THIS ONE POPUP, because `.leaflet-popup-*` is every popup in the product — the two
   property-data maps and the NGD broadcast map all draw the default chrome and must keep it.

   🚩 HIDING THE TIP IS PURELY COSMETIC — it is a rotated white square carrying Leaflet's own
   shadow, which a square card has no use for. It is NOT load-bearing for the hover, and an earlier
   version of this comment claimed it was, in the way most likely to invite shortening the linger.
   Measured in leaflet.css instead of reasoned out: `.leaflet-popup-tip-container` is
   `pointer-events: none`, so nothing "travels through" it, and the ~20px between card and pin comes
   from `.leaflet-popup { margin-bottom: 20px }`, which hiding the tip does not touch. That gap is
   pointer-dead either way — so `CARD_LINGER_MS` in coverage_map_controller.js is the ENTIRE
   mechanism carrying the pointer from the pin into the card, and shortening it breaks the link. */
.job-map-card .leaflet-popup-content-wrapper {
  background: transparent;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
}

/* 🪦 `width: auto !important` WAS HERE AND WAS THE WRONG LEVER, which is worth recording because
   it looks right. `Popup._updateLayout` measures its content and writes the answer back as an
   INLINE `style.width`, so releasing that width reads like handing the decision back to the
   design system. It hands it to the LAYOUT instead — and Leaflet's popup pane is
   `position: absolute` with no width, so an absolutely positioned `.leaflet-popup` inside it has
   ZERO available width and shrink-to-fit falls back to its **min**-content. Measured: the card's
   max-content is 173px and the card rendered at 57px, narrower than the 84px it was trying to
   fix. Leaflet is told the bounds instead (`CARD_OPTIONS` in coverage_map_controller.js) and
   keeps writing the width itself.

   What stays here is only the chrome the design system replaces. */
.job-map-card .leaflet-popup-content {
  margin: 0;
  font-size: inherit;
  line-height: inherit;
}

.job-map-card .leaflet-popup-tip {
  display: none;
}

/* 🚨 NOTHING HERE SIZES THE MAP CANVAS, AND THAT IS THE FIX (B-411).

   A `position: relative; width: 100%; height: 20rem; min-height: 20rem` rule used to sit here
   on `.os-leaflet-map-container, [data-os-leaflet-map-target="map"]`. Both halves were wrong,
   for different reasons.

   `.os-leaflet-map-container` matched NO element in the app — the class appeared only in this
   stylesheet. So its mobile companion, `@media (max-width: 768px) { .os-leaflet-map-container
   { height: 16rem } }`, was dead twice over: a dead selector carrying a declaration that the
   base rule's `min-height: 20rem` would have overridden anyway.

   🚩 THE LIVE HALF WAS THE HARMFUL ONE. `[data-os-leaflet-map-target="map"]` matches exactly
   one element — the canvas in `shared/_os_leaflet_map.html.erb` — which is a DS
   `.score-map__canvas` inside `.score-map--fill`. The DS declares `position: absolute; inset: 0`
   and NO height, so at equal specificity there was nothing to override `height`/`min-height`
   and this rule simply won them. An absolutely positioned box with `top: 0; bottom: 0` AND an
   explicit height is over-constrained: `bottom` is dropped and the canvas becomes a fixed 320px.

   That reinstated, one level down, the exact floor the `.score-map--fill` reconciliation
   (DS §59–63, B-217b) exists to remove. Measured on localhost at the wizard's real geometry:
   a 283px `overflow: hidden` frame holding a 320px canvas — the clipped band is the bottom
   37px, which is where `.score-map__brand` sits. So the OS logo that cl. 5.3.3 mandates
   rendered and was then cropped out of view — the outcome that reconciliation exists to prevent.

   Map sizing belongs to the DS: `.score-map` owns the box, `.score-map__canvas` fills it.
   Guard: the "map canvas" tripwire in spec/misc/design_system_foundation_spec.rb. */

/* Attribution styling */
.leaflet-control-attribution {
  background: rgba(255, 255, 255, 0.8) !important;
  font-size: 11px !important;
}

/* Zoom control styling */
.leaflet-control-zoom {
  border: none !important;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1) !important;
}

.leaflet-control-zoom a {
  background: #fff !important;
  border: 1px solid #e5e7eb !important;
  color: #374151 !important;
  font-size: 16px !important;
  font-weight: bold !important;
}

.leaflet-control-zoom a:hover {
  background: #f3f4f6 !important;
  border-color: #d1d5db !important;
}

/* Building overlay styles */
.building-outline {
  cursor: pointer;
}

.building-part {
  cursor: pointer;
}

/* Responsive adjustments */
@media (max-width: 768px) {
  .property-marker {
    transform: scale(0.8);
  }
}

/* Kanban placeholder appear animation */
@keyframes kanban-placeholder-appear {
  0% {
    opacity: 0;
    transform: scale(0.8);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

.kanban-placeholder-appear {
  animation: kanban-placeholder-appear 0.3s ease-out forwards;
}

/* ============================================
   SCORE Selection Components
   Shared styles for radio card selection UI
   Used by: quote cards, terms template selection
   ============================================ */

/* Base selection card styles */
.score-selection-card {
  transition: all 0.15s ease-in-out;
}

.score-selection-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* B-575 — the surveyor's recommended option (public quote page): a heavier border and a light fill.
   Selecting it still wins (the :has(.peer:checked) rule below), so the client's choice is unmistakable. */
.score-selection-card--recommended {
  border: 2px solid #2563eb;
  background-color: #f8fafc;
}

/* Selected state - uses CSS :has() for parent styling */
.score-selection-card:has(.peer:checked) {
  border-color: #2563eb !important;
  background-color: #eff6ff !important;
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.2), 0 4px 12px rgba(37, 99, 235, 0.15) !important;
}

.score-selection-card:has(.peer:checked):hover {
  background-color: #dbeafe !important;
}

.score-selection-card:has(.peer:focus) {
  outline: none;
}

.score-selection-card:focus-within {
  outline: none;
}

/* Radio circle indicator - transforms to blue check on selection */
.score-selection-card:has(.peer:checked) .score-radio-circle {
  border-color: #2563eb !important;
  background-color: #2563eb !important;
}

.score-selection-card:has(.peer:checked) .score-radio-check {
  opacity: 1 !important;
}

/* Inline radio variant - for non-card radio buttons (e.g., contact preference lists) */
.score-inline-radio:has(.peer:checked) .score-radio-circle {
  border-color: #2563eb !important;
  background-color: #2563eb !important;
}

.score-inline-radio:has(.peer:checked) .score-radio-check {
  opacity: 1 !important;
}

/* ============================================
   Prepare Stepper — Container Query Layout
   Switches from horizontal chips to vertical
   sidebar based on content area width (800px).
   ============================================ */
/* Shared stepper content max-width — only applied when sidebar is visible */
.stepper-chip-active { box-shadow: inset 0 -3px 0 #2563eb; }

.prepare-stepper-horizontal { display: block !important; }
.prepare-stepper-sidebar { display: none !important; }
.prepare-layout { flex-direction: column !important; gap: 0 !important; }
.prepare-content { display: flex; flex-direction: column; min-height: 0; width: 100% !important; min-width: 0 !important; }
.prepare-content .conflict-check-embed .p-6 { padding: 0 !important; }
.conflict-check-embed .bg-gray-50 > .border-b:first-child { display: none !important; }
.conflict-check-embed .rounded-lg,
.conflict-check-embed .rounded-md,
.conflict-check-embed .rounded { border-radius: 0 !important; }
.conflict-check-embed .space-y-8 > .bg-gray-50 { background: transparent !important; border: none !important; }
.conflict-check-embed .space-y-8 > .bg-gray-50 > .bg-white { padding: 0.75rem 0 !important; }

@container (min-width: 800px) {
  .prepare-stepper-horizontal { display: none !important; }
  .prepare-stepper-sidebar { display: flex !important; flex-direction: column; align-self: start; }
  .prepare-stepper-sidebar > a { box-shadow: none !important; }
  .prepare-layout { flex-direction: row !important; gap: 0 !important; padding: 1.25rem; }
  .prepare-content { margin-left: 1.25rem; }
}

/* prepare_conflict_v7 — the job Prepare stage draws its steps as DS tabs across the top at every width
   (shared/steppers/_tabs): the conflict check has its own navigator, and a sidebar stepper beside it made two
   navigation columns. The quotes stage still switches to its sidebar. */
@container (min-width: 800px) {
  .prepare-layout--tabs { flex-direction: column !important; padding: 0; }
  .prepare-layout--tabs .prepare-content { margin-left: 0; }
}

.prepare-stepper-scroll { -ms-overflow-style: none; scrollbar-width: none; }
.prepare-stepper-scroll::-webkit-scrollbar { display: none; }

.prepare-tab-shadow { box-shadow: 0 4px 8px -2px rgba(0, 0, 0, 0.12); }
.prepare-tab-active { box-shadow: inset 0 -3px 0 #2563eb; }

/* ============================================
   Confirm & Book stepper responsive layout.
   Mirrors prepare stepper breakpoints.
   ============================================ */
.confirm-stepper-horizontal { display: block !important; }
.confirm-stepper-sidebar { display: none !important; }
.confirm-layout { flex-direction: column !important; gap: 0 !important; }
.confirm-content { display: flex; flex-direction: column; min-height: 0; width: 100% !important; min-width: 0 !important; }

@container (min-width: 800px) {
  .confirm-stepper-horizontal { display: none !important; }
  .confirm-stepper-sidebar { display: flex !important; flex-direction: column; align-self: start; }
  .confirm-stepper-sidebar > a { box-shadow: none !important; }
  .confirm-layout { flex-direction: row !important; gap: 0 !important; padding: 1.25rem; }
  .confirm-content { margin-left: 1.25rem; }
}

.confirm-stepper-scroll { -ms-overflow-style: none; scrollbar-width: none; }
.confirm-stepper-scroll::-webkit-scrollbar { display: none; }

/* ============================================
   Report tab stepper — responsive layout
   ============================================ */
.report-stepper-horizontal { display: block !important; }
.report-stepper-sidebar { display: none !important; }
.report-layout { flex-direction: column !important; gap: 0 !important; }
.report-content { display: flex; flex-direction: column; min-height: 0; width: 100% !important; min-width: 0 !important; }

@container (min-width: 800px) {
  .report-stepper-horizontal { display: none !important; }
  .report-stepper-sidebar { display: flex !important; flex-direction: column; align-self: start; }
  .report-stepper-sidebar > a { box-shadow: none !important; }
  .report-layout { flex-direction: row !important; gap: 0 !important; padding: 1.25rem; }
  .report-content { margin-left: 1.25rem; }
}

.report-stepper-scroll { -ms-overflow-style: none; scrollbar-width: none; }
.report-stepper-scroll::-webkit-scrollbar { display: none; }
