/* ===== TogetherCRM design system, layered on top of Duralux (Bootstrap 5) =====
   Load order: bootstrap.min.css -> theme.min.css (Duralux) -> app.css (this file).

   Duralux owns the app chrome (sidebar, header, cards, buttons, forms). This file adds:
     - the design tokens both systems read
     - components Duralux has no equivalent for (.ss-* searchable select, custom checkbox)
     - a Tailwind-style utility subset, prefixed `tc-` wherever the plain name would collide
       with a Bootstrap utility (Bootstrap marks those !important, so load order can't settle it)

   The element reset below is scoped to `.tc-scope` (page content only) AND wrapped in :where(),
   which contributes zero specificity. That matters: without it the reset out-ranks Bootstrap
   components rendered inside the scope — .form-control lost its border and padding. With :where(),
   any real class wins and the reset only fills in where nothing else has an opinion. */

:where(.tc-scope) :where(*),:where(.tc-scope) :where(*)::before,:where(.tc-scope) :where(*)::after{box-sizing:border-box;border-width:0;border-style:solid;border-color:hsl(var(--border));--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}
:where(.tc-scope){line-height:1.5;-webkit-tap-highlight-color:transparent}
:where(.tc-scope) :where(hr){height:0;color:inherit;border-top-width:1px}
:where(.tc-scope) :where(h1,h2,h3,h4,h5,h6){font-size:inherit;font-weight:inherit;margin:0}
:where(.tc-scope) :where(a){color:inherit;text-decoration:inherit}
:where(.tc-scope) :where(b,strong){font-weight:bolder}
:where(.tc-scope) :where(button,input,optgroup,select,textarea){font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}
:where(.tc-scope) :where(button,select){text-transform:none}
:where(.tc-scope) :where(button,[type=button],[type=reset],[type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}
:where(.tc-scope) :where(table){text-indent:0;border-color:inherit;border-collapse:collapse}
:where(.tc-scope) :where(blockquote,dl,dd,figure,p,pre){margin:0}
:where(.tc-scope) :where(fieldset){margin:0;padding:0}
:where(.tc-scope) :where(legend){padding:0}
:where(.tc-scope) :where(ol,ul,menu){list-style:none;margin:0;padding:0}
:where(.tc-scope) :where(textarea){resize:vertical}
:where(.tc-scope) :where(input)::placeholder,:where(.tc-scope) :where(textarea)::placeholder{opacity:1;color:hsl(var(--muted-foreground))}
:where(.tc-scope) :where(button,[role=button]){cursor:pointer}
:where(.tc-scope) :where(img,svg,video,canvas){display:block;vertical-align:middle}
:where(.tc-scope) :where(img,video){max-width:100%;height:auto}
:where(.tc-scope) :where([hidden]){display:none}
:root{
  --background:216 33% 97%;--foreground:20 14.3% 4.1%;
  --card:0 0% 100%;--card-foreground:20 14.3% 4.1%;
  --popover:0 0% 100%;--popover-foreground:20 14.3% 4.1%;
  --primary:217.2 91.2% 59.8%;--primary-foreground:210 40% 98%;
  --secondary:210 40% 96%;--secondary-foreground:222.2 84% 4.9%;
  --muted:210 40% 96%;--muted-foreground:215.4 16.3% 46.9%;
  --accent:210 40% 96%;--accent-foreground:222.2 84% 4.9%;
  --destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;
  --border:214 30% 89%;--input:214 30% 89%;--ring:217.2 91.2% 59.8%;--radius:.75rem;
  --sidebar-background:0 0% 100%;--sidebar-foreground:20 14.3% 4.1%;
  --sidebar-primary:217.2 91.2% 59.8%;--sidebar-primary-foreground:210 40% 98%;
  --sidebar-accent:210 40% 96%;--sidebar-accent-foreground:222.2 84% 4.9%;
  --sidebar-border:214.3 31.8% 91.4%;--sidebar-ring:222.2 84% 4.9%;
  --success:142 71% 45%;--warning:38 92% 50%;
}
/* Dark mode is TWO things working together: this block flips our tokens, and `app-skin-dark` on
   <html> turns on Duralux's own dark skin for the chrome it owns (sidebar, header, card, form,
   table). The layout adds both classes at once — see the note in _Layout's <head>.

   These values are deliberately Duralux's own dark palette rather than a separate scheme, so a
   token-built page sits flush against theme-built chrome instead of being a slightly different
   shade of navy:
     body #121a2d · card/sidebar/header #0f172a · border #1b2436 · raised #1c2438 · muted text #b1b4c0 */
.dark{
  --background:222 43% 12%;--foreground:0 0% 100%;
  --card:222 47% 11%;--card-foreground:0 0% 100%;
  --popover:222 47% 11%;--popover-foreground:0 0% 100%;
  --primary:217.2 91.2% 59.8%;--primary-foreground:210 40% 98%;
  --secondary:223 33% 17%;--secondary-foreground:0 0% 100%;
  --muted:223 33% 17%;--muted-foreground:228 11% 72%;
  --accent:223 33% 17%;--accent-foreground:0 0% 100%;
  --destructive:0 62.8% 30.6%;--destructive-foreground:210 40% 98%;
  --border:220 33% 16%;--input:220 33% 16%;--ring:217.2 91.2% 59.8%;
  --sidebar-background:222 47% 11%;--sidebar-foreground:0 0% 100%;
  --sidebar-primary:217.2 91.2% 59.8%;--sidebar-primary-foreground:210 40% 98%;
  --sidebar-accent:223 33% 17%;--sidebar-accent-foreground:0 0% 100%;
  --sidebar-border:220 33% 16%;--sidebar-ring:217.2 91.2% 59.8%;
}
:where(.tc-scope) :where(*){border-color:hsl(var(--border))}
body{background-color:hsl(var(--background));color:hsl(var(--foreground))}


/* Component tokens.
   .card is deliberately NOT defined here — Duralux owns the card look, so every existing
   page picks up the theme styling without touching its markup. Table rules stay scoped. */
:where(.tc-scope) :where(table){background-color:hsl(var(--card));color:hsl(var(--card-foreground))}
:where(.tc-scope) :where(table) th{border-color:hsl(var(--border));background-color:hsl(var(--muted));color:hsl(var(--muted-foreground))}
:where(.tc-scope) :where(table) td{border-color:hsl(var(--border));color:hsl(var(--card-foreground))}
:where(.tc-scope) :where(table) tr{border-color:hsl(var(--border))}

/* ---- Utility subset (Tailwind-compatible) ---- */
.relative{position:relative}.absolute{position:absolute}.fixed{position:fixed}.tc-sticky{position:sticky}
.inset-0{inset:0}.top-0{top:0}.left-0{left:0}.right-0{right:0}.bottom-0{bottom:0}
.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}
.left-3{left:.75rem}.right-3{right:.75rem}.top-2\.5{top:.625rem}.top-3{top:.75rem}.-top-0\.5{top:-.125rem}.-right-0\.5{right:-.125rem}.mt-2{margin-top:.5rem}
.w-52{width:13rem}.w-60{width:15rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.tc-px-1{padding-left:.25rem;padding-right:.25rem}
.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.block{display:block}.inline-block{display:inline-block}.hidden{display:none}.contents{display:contents}
.h-full{height:100%}.h-screen{height:100vh}.min-h-screen{min-height:100vh}.w-full{width:100%}.h-4{height:1rem}.w-4{width:1rem}.h-5{height:1.25rem}.w-5{width:1.25rem}.h-6{height:1.5rem}.w-6{width:1.5rem}.h-8{height:2rem}.w-8{width:2rem}.h-9{height:2.25rem}.w-9{width:2.25rem}.h-10{height:2.5rem}.w-10{width:2.5rem}.h-2{height:.5rem}.w-2{width:.5rem}.h-2\.5{height:.625rem}.w-2\.5{width:.625rem}
.w-64{width:16rem}.w-56{width:14rem}.w-72{width:18rem}.min-w-0{min-width:0}
.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.grow{flex-grow:1}
.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}
.items-center{align-items:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-baseline{align-items:baseline}
.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}
.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.tc-gap-3{gap:.75rem}.tc-gap-4{gap:1rem}.tc-gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}
.gap-x-4{column-gap:1rem}.gap-x-6{column-gap:1.5rem}.gap-x-8{column-gap:2rem}.gap-y-2{row-gap:.5rem}.gap-y-3{row-gap:.75rem}
.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
.overflow-hidden{overflow:hidden}.overflow-auto{overflow:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-auto{overflow-x:auto}
.tc-rounded{border-radius:.25rem}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-lg{border-radius:var(--radius)}.rounded-xl{border-radius:.75rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}
.tc-border{border-width:1px}.tc-border-0{border-width:0}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-t-2{border-top-width:2px}
.border-border{border-color:hsl(var(--border))}.border-transparent{border-color:transparent}.border-input{border-color:hsl(var(--input))}.tc-border-primary{border-color:hsl(var(--primary))}
.border-b-2{border-bottom-width:2px}.-mb-px{margin-bottom:-1px}.tc-pb-3{padding-bottom:.75rem}.mt-0\.5{margin-top:.125rem}.w-44{width:11rem}
.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.tc-p-3{padding:.75rem}.tc-p-4{padding:1rem}.tc-p-5{padding:1.25rem}.p-6{padding:1.5rem}
.tc-px-2{padding-left:.5rem;padding-right:.5rem}.tc-px-2\.5{padding-left:.625rem;padding-right:.625rem}.tc-px-3{padding-left:.75rem;padding-right:.75rem}.tc-px-4{padding-left:1rem;padding-right:1rem}.tc-px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.p-8{padding:2rem}
.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.pb-2{padding-bottom:.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.tc-py-3{padding-top:.75rem;padding-bottom:.75rem}.tc-py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}
.pl-3{padding-left:.75rem}.pl-9{padding-left:2.25rem}.pl-10{padding-left:2.5rem}.pr-3{padding-right:.75rem}.pr-4{padding-right:1rem}
.m-0{margin:0}.tc-mx-auto{margin-left:auto;margin-right:auto}.ml-auto{margin-left:auto}.mr-auto{margin-right:auto}
.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.tc-mb-3{margin-bottom:.75rem}.tc-mb-4{margin-bottom:1rem}.tc-mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.tc-mt-3{margin-top:.75rem}.tc-mt-4{margin-top:1rem}.tc-mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.mt-auto{margin-top:auto}
.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}
.text-xs{font-size:.75rem;line-height:1rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}
.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}
.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}
.leading-none{line-height:1}.leading-tight{line-height:1.25}
.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}
.text-foreground{color:hsl(var(--foreground))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.tc-text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.tc-text-white{color:#fff}.text-destructive{color:hsl(var(--destructive))}.text-card-foreground{color:hsl(var(--card-foreground))}
.text-green-600{color:#16a34a}.text-green-700{color:#15803d}.text-blue-600{color:#2563eb}.text-blue-700{color:#1d4ed8}.text-red-600{color:#dc2626}.text-yellow-600{color:#ca8a04}.text-amber-600{color:#d97706}.tc-text-gray-400{color:#9ca3af}.tc-text-gray-500{color:#6b7280}.tc-text-gray-600{color:#4b5563}.text-gray-700{color:#374151}.text-gray-900{color:#111827}
.bg-background{background-color:hsl(var(--background))}.bg-card{background-color:hsl(var(--card))}.tc-bg-muted{background-color:hsl(var(--muted))}.tc-bg-primary{background-color:hsl(var(--primary))}.tc-bg-white{background-color:#fff}.tc-bg-transparent{background-color:transparent}.bg-sidebar{background-color:hsl(var(--sidebar-background))}
.tc-bg-primary\/10{background-color:hsl(var(--primary) / .1)}.tc-bg-primary\/5{background-color:hsl(var(--primary) / .05)}.tc-bg-muted\/50{background-color:hsl(var(--muted) / .5)}.bg-accent{background-color:hsl(var(--accent))}
.bg-green-50{background-color:#f0fdf4}.bg-green-100{background-color:#dcfce7}.bg-green-500{background-color:#22c55e}.bg-blue-50{background-color:#eff6ff}.bg-blue-100{background-color:#dbeafe}.bg-blue-500{background-color:#3b82f6}.bg-blue-600{background-color:#2563eb}.bg-red-50{background-color:#fef2f2}.bg-red-500{background-color:#ef4444}.bg-yellow-100{background-color:#fef9c3}.bg-yellow-400{background-color:#facc15}.bg-amber-500{background-color:#f59e0b}.tc-bg-gray-100{background-color:#f3f4f6}.tc-bg-gray-200{background-color:#e5e7eb}.bg-slate-800{background-color:#1e293b}.bg-slate-900{background-color:#0f172a}
.tc-shadow-sm{--tw-shadow:0 1px 2px 0 rgb(0 0 0 / .05);box-shadow:var(--tw-shadow)}.tc-shadow{--tw-shadow:0 1px 3px 0 rgb(0 0 0 / .1),0 1px 2px -1px rgb(0 0 0 / .1);box-shadow:var(--tw-shadow)}.tc-shadow-md{--tw-shadow:0 4px 6px -1px rgb(0 0 0 / .1),0 2px 4px -2px rgb(0 0 0 / .1);box-shadow:var(--tw-shadow)}.tc-shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / .1),0 4px 6px -4px rgb(0 0 0 / .1);box-shadow:var(--tw-shadow)}.shadow-none{box-shadow:none}
.shadow-soft{box-shadow:0 1px 2px 0 rgb(20 37 61 / .04),0 6px 20px 0 rgb(20 37 61 / .04)}
.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;user-select:none}.pointer-events-none{pointer-events:none}
.transition{transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}
.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-100{opacity:1}
.space-y-1>*+*{margin-top:.25rem}.space-y-2>*+*{margin-top:.5rem}.space-y-3>*+*{margin-top:.75rem}.space-y-4>*+*{margin-top:1rem}.space-y-6>*+*{margin-top:1.5rem}
.divide-y>*+*{border-top-width:1px}
.divide-border>*+*{border-color:hsl(var(--border))}
.max-w-xs{max-width:20rem}.max-w-sm{max-width:24rem}.max-w-md{max-width:28rem}.max-w-lg{max-width:32rem}.max-w-2xl{max-width:42rem}
.aspect-square{aspect-ratio:1/1}.object-cover{object-fit:cover}
.min-w-\[16px\]{min-width:16px}.h-\[18px\]{height:18px}.min-w-\[18px\]{min-width:18px}
.ring-2{box-shadow:0 0 0 2px hsl(var(--ring))}
.animate-spin{animation:spin 1s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.animate-fade-in{animation:fadeIn .25s ease-in-out}
@keyframes fadeIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* Hover/focus */
.hover\:tc-bg-muted:hover{background-color:hsl(var(--muted))}
.hover\:tc-bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}
.hover\:bg-accent:hover{background-color:hsl(var(--accent))}
.hover\:tc-bg-primary\/10:hover{background-color:hsl(var(--primary) / .1)}
.hover\:tc-bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}
.hover\:tc-bg-gray-100:hover{background-color:#f3f4f6}
.hover\:bg-gray-50:hover{background-color:#f9fafb}
.hover\:text-foreground:hover{color:hsl(var(--foreground))}
.hover\:tc-text-primary:hover{color:hsl(var(--primary))}
.hover\:tc-shadow-md:hover{box-shadow:0 4px 6px -1px rgb(0 0 0 / .1),0 2px 4px -2px rgb(0 0 0 / .1)}
.hover\:underline:hover{text-decoration-line:underline}
.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}
.focus-visible\:outline-none:focus-visible{outline:2px solid transparent}

@media (min-width:768px){
  .md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
}
@media (min-width:1024px){
  .lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
}

/* ── Searchable select (progressive enhancement over a native <select>) ───────── */
.ss { position: relative; display: block; }
/* The native select stays for binding + validation, just not visible.
   Matched structurally, not by the .ss-native class: htmx settles the attributes in
   htmx.config.attributesToSettle (class, style, width, height) onto any element whose id also
   existed before the swap, ~20ms after it. That re-applied the server's class="form-control" and
   stripped the .ss-native the enhancer had just added, leaving the raw select visible under the
   styled one -- the "two dropdowns" in the stage dialog. Being a child of .ss is structural, so
   attribute settling cannot undo it. */
.ss > select,
.ss-native {
    position: absolute; width: 1px; height: 1px;
    opacity: 0; pointer-events: none; margin: 0; padding: 0; border: 0;
}
.ss-trigger {
    display: flex; align-items: center; gap: .5rem; width: 100%;
    padding: .5rem .75rem;
    border: 1px solid hsl(var(--border)); border-radius: .5rem;
    background: hsl(var(--card)); color: hsl(var(--foreground));
    font-size: .875rem; font-family: inherit; text-align: left; cursor: pointer;
}
.ss-trigger:hover { background: hsl(var(--muted) / .4); }
.ss-trigger:focus-visible { outline: 2px solid hsl(var(--primary) / .4); outline-offset: 1px; }
.ss-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-placeholder { color: hsl(var(--muted-foreground)); }
.ss-chevron { flex-shrink: 0; color: hsl(var(--muted-foreground)); }

.ss-panel {
    /* Grow to fit the longest option instead of being pinned to the trigger width,
       which was ellipsising short labels like "Not Started". */
    position: absolute; left: 0; right: auto; top: calc(100% + 4px); z-index: 60;
    min-width: 100%; width: max-content; max-width: min(22rem, 90vw);
    border: 1px solid hsl(var(--border)); border-radius: .625rem;
    background: hsl(var(--card));
    box-shadow: 0 10px 25px -5px rgb(0 0 0 / .18), 0 4px 10px -6px rgb(0 0 0 / .12);
    overflow: hidden;
}
.ss-panel.ss-up { top: auto; bottom: calc(100% + 4px); }

.ss-search {
    display: flex; align-items: center; gap: .5rem;
    padding: .5rem .75rem; border-bottom: 1px solid hsl(var(--border));
    color: hsl(var(--muted-foreground));
}
.ss-search input {
    flex: 1; border: 0; outline: none; background: transparent;
    font-size: .875rem; font-family: inherit; color: hsl(var(--foreground)); padding: 0;
}

.ss-list { list-style: none; margin: 0; padding: .25rem; max-height: 240px; overflow-y: auto; }
.ss-opt {
    display: flex; align-items: center; gap: .5rem;
    padding: .5rem .625rem; border-radius: .375rem;
    font-size: .875rem; cursor: pointer; user-select: none;
}
.ss-opt.ss-active { background: hsl(var(--muted)); }
.ss-opt[aria-selected="true"] { font-weight: 500; }
.ss-opt.ss-disabled { opacity: .5; cursor: not-allowed; }
.ss-check { width: 14px; flex-shrink: 0; color: hsl(var(--foreground)); display: inline-flex; }
.ss-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-opt { min-width: 0; }
.ss-empty { padding: 1.25rem .75rem; text-align: center; font-size: .8125rem; color: hsl(var(--muted-foreground)); }

/* ===== Page spacing system =========================================================
   Duralux reserves .nxl-content{padding-top:95px} for its fixed .page-header bar. We
   don't render that bar, so it was dead space; the gutters instead come from
   .main-content, which we now wrap page content in.
   Rhythm follows a 4/8px scale with a clear section hierarchy: 24 / 32 / 40. */

.nxl-content { padding-top: 0; }

/* Duralux scopes this as .nxl-container .nxl-content .main-content (specificity 0,3,0),
   so a bare .main-content rule loses. Match the chain to override the gutters. */
.nxl-container .nxl-content .main-content {
    padding: 28px 32px 48px;
    /* NOT overflow-x:hidden. Setting it forces overflow-y to compute as `auto`, which makes
       this a clipping context and crops any absolutely-positioned dropdown that extends past
       the content box. Wide tables already scroll inside their own .overflow-x-auto wrapper. */
    overflow: visible;
}
@media (max-width: 1399px) { .nxl-container .nxl-content .main-content { padding: 24px 24px 40px; } }
@media (max-width: 991px)  { .nxl-container .nxl-content .main-content { padding: 20px 16px 32px; } }

/* Page content must be able to shrink, or a wide table forces the whole page wider
   than the viewport instead of scrolling within its own container. */
.main-content > #content { min-width: 0; }
.tc-scope .overflow-x-auto { max-width: 100%; }

/* Vertical rhythm between page sections. Applied on the scope so every module page
   gets the same cadence without touching 48 views. */
.tc-scope > * + * { margin-top: 20px; }

/* Comfortable table density — the theme's default rows read tight for data-heavy CRM
   tables, and cramped rows were part of what looked unprofessional. */
.tc-scope table th { padding-top: .75rem; padding-bottom: .75rem; white-space: nowrap; }
.tc-scope table td { padding-top: .875rem; padding-bottom: .875rem; }

/* ===== Checkbox ====================================================================
   Bootstrap/Duralux style checkboxes through .form-check-input. Our custom control is
   for bare checkboxes only — without the :not() guard the two fought and the box
   rendered as an empty grey square. */
input[type=checkbox]:not(.form-check-input) {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    width: 1rem; height: 1rem; flex-shrink: 0; margin: 0; cursor: pointer; position: relative;
    border: 1.5px solid #c9d2e0; border-radius: 4px; background-color: #fff;
    transition: background-color .15s, border-color .15s, box-shadow .15s;
    vertical-align: middle; display: inline-block;
}
input[type=checkbox]:not(.form-check-input):hover { border-color: #3454d1; }
input[type=checkbox]:not(.form-check-input):focus-visible {
    outline: none; box-shadow: 0 0 0 3px rgba(52, 84, 209, .25);
}
input[type=checkbox]:not(.form-check-input):checked { background-color: #3454d1; border-color: #3454d1; }
input[type=checkbox]:not(.form-check-input):checked::after {
    content: ""; position: absolute; left: 4.5px; top: 1px; width: 4px; height: 8px;
    border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
input[type=checkbox]:not(.form-check-input):disabled { opacity: .5; cursor: not-allowed; }

/* Bootstrap-classed checkboxes render in Bootstrap's default blue (#0d6efd), which clashes
   with Duralux's brand blue used by the sidebar, buttons and links. Align them, and bump the
   box to 1rem so the hit area is comfortable. */
.form-check-input { width: 1rem; height: 1rem; margin-top: .175rem; border-color: #c9d2e0; }
.form-check-input:checked { background-color: #3454d1; border-color: #3454d1; }
.form-check-input:focus {
    border-color: #3454d1;
    box-shadow: 0 0 0 3px rgba(52, 84, 209, .25);
}

/* ===== Buttons =====================================================================
   All buttons now use Duralux's .btn classes. The ones converted from the old utility
   markup carry an inline <svg> instead of an <i class="feather-… me-2">, so they need a
   gap — scoped with :has(> svg) so icon-font buttons don't get spacing twice. */
.tc-scope .btn:has(> svg) { gap: .5rem; }
.tc-scope .btn > svg { flex-shrink: 0; }

/* A disabled link-button must not stay clickable. */
.tc-scope a.btn.disabled, .tc-scope a.btn[aria-disabled="true"] {
    pointer-events: none; opacity: .55;
}

/* Bootstrap's .table-responsive is overflow-x:auto, and a scroll container clips on BOTH axes --
   overflow-x:auto computes overflow-y to auto. Every row-action kebab menu inside one was cut off
   at the card's edge (on a short table, Delete was unreachable). While a menu is open, let the
   container overflow; it goes back to scrolling the moment the menu closes. */
.table-responsive:has(.dropdown-menu.show) { overflow: visible; }

/* ===== Contract template editor =====
   Ported from the PDFMaker reference. The page wrapper is sized in points x scale by the view;
   the canvas and the field overlay sit on top of each other inside it. */
.tpl-surface { display: flex; flex-direction: column; gap: 20px; align-items: center; }
.tpl-page {
    position: relative; background: #fff;
    border: 1px solid var(--bs-border-color, #e5e7eb);
    box-shadow: 0 2px 10px rgba(16, 24, 40, .08);
}
.tpl-page .page-badge {
    position: absolute; top: -10px; left: 8px; background: #12233b; color: #fff;
    font-size: 11px; padding: 2px 8px; border-radius: 4px; z-index: 3;
}
.canvas-host { position: absolute; inset: 0; z-index: 1; }
.canvas-host canvas { display: block; }
.overlay { position: absolute; inset: 0; z-index: 2; }
.overlay.placing { cursor: crosshair; }

.field-box {
    position: absolute; border: 1.5px solid #3454d1;
    background: rgba(52, 84, 209, .10); border-radius: 3px;
    font-size: 11px; overflow: hidden; display: flex; align-items: center;
    padding: 0 4px; cursor: grab; user-select: none;
}
.field-box .fb-label { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
.field-box.selected { outline: 2px solid #ffab00; border-color: #ffab00; background: rgba(255, 171, 0, .15); z-index: 5; }
.field-box.ft-signature, .field-box.ft-initials { background: rgba(16, 140, 90, .12); border-color: #14875a; }
.field-box.ft-statictext { background: rgba(120, 120, 120, .12); border-color: #8a8a8a; }
.field-box.ft-table { background: rgba(150, 90, 200, .12); border-color: #7d3fc8; }
.field-box.has-table { display: block; padding: 0; overflow: hidden; align-items: stretch; }

.field-box .resize-handle {
    position: absolute; right: -5px; bottom: -5px; width: 12px; height: 12px;
    background: #fff; border: 2px solid #3454d1; border-radius: 3px;
    cursor: nwse-resize; z-index: 6; touch-action: none;
}
.field-box.selected .resize-handle { border-color: #ffab00; }

.fb-tbl { width: 100%; height: 100%; border-collapse: collapse; table-layout: fixed; font-size: inherit; }
.fb-tbl th, .fb-tbl td {
    padding: 1px 3px; text-align: left; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.fb-tbl.bd th, .fb-tbl.bd td { border: .5px solid #7d3fc8; }

/* Palette + placed-field list */
.palette-btn { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; }
.palette-btn.armed { background: #3454d1; color: #fff; border-color: #3454d1; }
.palette-btn.armed .fld-ic { background: rgba(255, 255, 255, .25); color: #fff; }
.fld-ic {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: 5px; font-size: 11px; font-weight: 700;
    background: rgba(52, 84, 209, .12); color: #3454d1; flex: 0 0 auto;
}
.fld-ic.ft-signature, .fld-ic.ft-initials { background: rgba(16, 140, 90, .14); color: #14875a; }
.fld-ic.ft-statictext { background: rgba(120, 120, 120, .16); color: #555; }
.fld-ic.ft-table { background: rgba(125, 63, 200, .14); color: #7d3fc8; }

.fld-group-hd { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: #6c757d; margin: 12px 0 4px; font-weight: 700; }
.fld-row {
    display: flex; align-items: center; gap: 8px; padding: 7px 8px; border-radius: 7px;
    cursor: pointer; border: 1px solid transparent;
}
.fld-row:hover { background: rgba(52, 84, 209, .06); }
.fld-row.sel { background: rgba(255, 171, 0, .12); border-color: #ffab00; }
.fld-main { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.fld-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.icon-btn { border: none; background: transparent; cursor: pointer; font-size: 16px; line-height: 1; padding: 2px 6px; border-radius: 5px; }
.icon-btn.danger { color: #dc3545; }
.icon-btn.danger:hover { background: rgba(220, 53, 69, .12); }

/* Style + table panels */
.style-panel { border: 1px solid var(--bs-border-color, #e5e7eb); border-radius: 8px; padding: 10px; display: flex; flex-direction: column; gap: 8px; }
.style-row { display: flex; align-items: center; gap: 8px; min-height: 30px; flex-wrap: wrap; }
.style-lbl { font-size: 12px; color: #6c757d; font-weight: 600; }
.chk { display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; margin: 0; }
.style-row input[type=color] { width: 36px; height: 28px; padding: 2px; border-radius: 6px; cursor: pointer; }
.w-num { width: 68px; }
.align-btns { display: inline-flex; margin-left: auto; border: 1px solid var(--bs-border-color, #e5e7eb); border-radius: 6px; overflow: hidden; }
.align-btn { border: none; background: #fff; cursor: pointer; padding: 3px 10px; font-size: 14px; }
.align-btn.on { background: #3454d1; color: #fff; }

.tbl-editor { border: 1px solid var(--bs-border-color, #e5e7eb); border-radius: 8px; padding: 10px; margin-bottom: 12px; }
.tbl-eh { display: flex; align-items: center; justify-content: space-between; font-size: 12px; font-weight: 700; color: #6c757d; text-transform: uppercase; margin: 6px 0 4px; }
.tbl-col, .tbl-row-ed { display: flex; gap: 4px; align-items: center; margin-bottom: 4px; }
.tbl-col input:first-child, .tbl-row-ed input { flex: 1; min-width: 0; }

/* Upload dropzone, shared by the template upload and the bid attachments */
.tpl-dropzone {
    border: 2px dashed var(--bs-border-color, #d0d5dd); border-radius: 12px;
    padding: 3rem 1rem; text-align: center; cursor: pointer; transition: background .15s ease;
}
.tpl-dropzone:hover { background: rgba(52, 84, 209, .03); }

/* The rubber band drawn while dragging out a new field. */
.field-band {
    position: absolute; z-index: 7; pointer-events: none;
    border: 1.5px dashed #3454d1; background: rgba(52, 84, 209, .12); border-radius: 3px;
}

/* ===== Dark-mode polish =====
   Duralux's dark skin sets `body{color:#b1b4c0!important}` and then whitens a fixed list of
   selectors (h1-h6, .h1-.h6, a, .btn, .form-control …). Anything outside that list inherits the
   muted grey — including the big stat numbers on the dashboard and the module headers, which are
   the figures people actually came to read. These put them back to full contrast.
   !important is required only because the rule being corrected is itself !important. */
html.app-skin-dark .fs-1,
html.app-skin-dark .fs-2,
html.app-skin-dark .fs-3,
html.app-skin-dark .fs-4,
html.app-skin-dark .fs-5 { color: #fff !important; }

/* Soft badges keep their hue but need a darker ground to sit on. */
html.app-skin-dark .bg-soft-primary { background-color: rgba(52, 84, 209, .18) !important; }
html.app-skin-dark .bg-soft-success { background-color: rgba(16, 140, 90, .20) !important; }
html.app-skin-dark .bg-soft-warning { background-color: rgba(255, 171, 0, .18) !important; }
html.app-skin-dark .bg-soft-danger  { background-color: rgba(220, 53, 69, .20) !important; }
html.app-skin-dark .bg-soft-info    { background-color: rgba(13, 202, 240, .16) !important; }
html.app-skin-dark .bg-soft-secondary { background-color: rgba(177, 180, 192, .16) !important; }

/* The contract-template editor draws the PDF on a white page; keep that white in dark mode, and
   lift the surround so the page edge stays visible. */
html.app-skin-dark .tpl-page { background: #fff; border-color: #1b2436; }
html.app-skin-dark .tpl-dropzone { border-color: #1b2436; }
html.app-skin-dark .tpl-dropzone:hover { background: rgba(52, 84, 209, .08); }
html.app-skin-dark .align-btn { background: #1c2438; color: #fff; }
html.app-skin-dark .align-btn.on { background: #3454d1; }
html.app-skin-dark .fld-row:hover { background: rgba(52, 84, 209, .12); }

/* ===== ApexCharts in dark mode =====
   Apex renders its labels as SVG <text>, so they take `fill`, not `color` — the legend is the one
   exception because it's real HTML. None of it inherits the theme's dark text colour, so axis
   labels, the donut's centre total and the legend all stayed near-black on a near-black card.
   Done in CSS rather than in each chart's options so it covers the dashboard, Reports and anything
   added later, and survives a chart re-render. */
html.app-skin-dark .apexcharts-text,
html.app-skin-dark .apexcharts-text tspan,
html.app-skin-dark .apexcharts-xaxis-label,
html.app-skin-dark .apexcharts-yaxis-label,
html.app-skin-dark .apexcharts-datalabel,
html.app-skin-dark .apexcharts-datalabel-label { fill: #b1b4c0 !important; }

/* The number in the middle of a donut is the headline, so it gets full contrast. */
html.app-skin-dark .apexcharts-datalabel-value,
html.app-skin-dark .apexcharts-title-text { fill: #fff !important; }

html.app-skin-dark .apexcharts-legend-text { color: #b1b4c0 !important; }

/* Grid and axis lines: the charts pass a light #eef2f7 in their options, which reads as bright
   scratches on a dark card. */
html.app-skin-dark .apexcharts-gridline,
html.app-skin-dark .apexcharts-grid-borders line,
html.app-skin-dark .apexcharts-xaxis line,
html.app-skin-dark .apexcharts-yaxis line { stroke: #1b2436 !important; }

/* Tooltips ship white with dark text. */
html.app-skin-dark .apexcharts-tooltip,
html.app-skin-dark .apexcharts-tooltip.apexcharts-theme-light {
    background: #0f172a !important;
    border-color: #1b2436 !important;
    color: #fff !important;
}
html.app-skin-dark .apexcharts-tooltip-title,
html.app-skin-dark .apexcharts-xaxistooltip,
html.app-skin-dark .apexcharts-yaxistooltip {
    background: #1c2438 !important;
    border-color: #1b2436 !important;
    color: #fff !important;
}

/* Bootstrap's .text-secondary is #6c757d — fine on white, muddy on a dark card. The theme whitens
   .text-muted but not this one, so soft "secondary" badges (e.g. "Sample trend") came out
   grey-on-grey. */
html.app-skin-dark .text-secondary { color: #b1b4c0 !important; }

/* ===== Leaflet in dark mode =====
   The tiles stay the keyless OSM ones (see js/map-tiles.js for why) and are darkened here with a
   filter: invert flips the bright sheet to dark and the labels to light, and hue-rotate puts the
   colours back the right way round so water reads blue rather than orange.

   Applied to .leaflet-tile-pane, NOT the map container: markers, popups and controls live in other
   panes and must not be inverted with it. */
html.app-skin-dark .leaflet-tile-pane {
    filter: invert(1) hue-rotate(180deg) brightness(.92) contrast(.88) saturate(.85);
}
html.app-skin-dark .leaflet-container { background: #121a2d; }
html.app-skin-dark .leaflet-bar a,
html.app-skin-dark .leaflet-control-zoom a {
    background: #0f172a; color: #fff; border-color: #1b2436;
}
html.app-skin-dark .leaflet-bar a:hover { background: #1c2438; }
html.app-skin-dark .leaflet-control-attribution {
    background: rgba(15, 23, 42, .85) !important; color: #b1b4c0;
}
html.app-skin-dark .leaflet-control-attribution a { color: #7fa0ff; }
html.app-skin-dark .leaflet-popup-content-wrapper,
html.app-skin-dark .leaflet-popup-tip {
    background: #0f172a; color: #fff; box-shadow: 0 4px 24px rgba(0, 0, 0, .6);
}
html.app-skin-dark .leaflet-popup-content a { color: #7fa0ff; }
html.app-skin-dark .leaflet-popup-close-button { color: #b1b4c0 !important; }
