/* ═══════════════════════════════════════════════════════════════════
   app-dark.css — Blueprint Intelligence dark theme for the app portals
   ───────────────────────────────────────────────────────────────────
   Loop 1: the PM portal. Served statically from /public and linked
   AFTER v5.css inside the PM shell heads (pmShellHead / pmShellHeadStep5),
   so only PM pages opt in this loop. Reuses the slate tokens already
   defined in v5.css (--slate-800/700, --slate-line, --slate-line-dim,
   --botanical, --powder, --cream, --copper). Does NOT redefine --powder:
   the app value #A8C5DA is accepted (visually identical to the mockup's
   #9FC2D9 — the one intentional deviation).

   The textured concrete page FRAME + solid --slate-800 data panels come
   from the approved mockup pm-dashboard-dark-concrete.html.

   Motion follows the animation standards: portals are visited tens-to-
   hundreds of times daily → tokens only. Button press feedback stays in
   the 100–160ms ease-out band; no scroll reveals, no cinematic motion.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  /* ink/muted are not defined globally in v5.css — define them here so
     the dark app surfaces have a warm off-white text + muted secondary. */
  --ink: #EDE9E0;
  --muted: rgba(237, 233, 224, .58);
}

/* ── Concrete textured page frame ──────────────────────────────────────
   TWIN COPY of the .concrete / .concrete::before / .grain rules in
   public/theme.css (~lines 58–81). The app owns its own copy so its
   rendered output never depends on theme.css. If a value changes, change
   it in BOTH files. Textures load from the already-served absolute paths
   /media/landing/textures/{concrete-dark,grain-grey}.webp. */
.concrete {
  background-color: var(--slate-900, #161c22);
  background-image:
    radial-gradient(ellipse 1200px 700px at 12% -10%, rgba(159,194,217,.05), transparent 60%),
    radial-gradient(ellipse 900px 600px at 92% 108%, rgba(94,140,74,.05), transparent 60%),
    url('/media/landing/textures/concrete-dark.webp'),
    linear-gradient(168deg, var(--slate-800, #1c242c) 0%, var(--slate-900, #161c22) 46%, #10151a 100%);
  background-size: auto, auto, cover, auto;
  background-position: center, center, center, center;
  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
  position: relative;
  isolation: isolate;
}
.concrete::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .06;
  filter: brightness(.4);
  background-image: url('/media/landing/textures/grain-grey.webp');
  background-repeat: repeat;
  background-size: 768px 768px;
}
.grain {
  position: absolute; inset: 0; pointer-events: none; opacity: .04; filter: brightness(.4);
  background-image: url('/media/landing/textures/grain-grey.webp');
  background-repeat: repeat;
  background-size: 768px 768px;
}

/* ── Solid data panel ──────────────────────────────────────────────────
   All data on the concrete frame sits on a SOLID --slate-800 panel. */
.panel {
  background: var(--slate-800);
  border: 1px solid var(--slate-line-dim);
  border-radius: 14px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
}

/* ── Dark body base ────────────────────────────────────────────────────
   PM shells set <body class="concrete texture-grain on-dark">; kill the
   old light grid-paper background and go to ink text. */
body.concrete {
  color: var(--ink);
  background-attachment: fixed;
}

/* ═══════ Dashboard surface (keyed to existing PM class names) ═════════ */

.pm-greet { color: var(--cream); }
.pm-greet .name { color: var(--powder); }

/* stat cards → solid slate panels; Bebas number in cream, with accent
   (powder) + green (botanical) modifiers preserved by renderStats. */
.stat {
  background: var(--slate-800);
  border: 1px solid var(--slate-line-dim);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
}
.stat .num { color: var(--cream); }
.stat.accent .num { color: var(--powder); }
.stat.green .num  { color: var(--botanical); }
.stat .lbl { color: var(--muted); }

/* primary CTA — botanical, white text, radius 13, press feedback */
.pm-cta {
  background: var(--botanical);
  color: #fff;
  border-radius: 13px;
  box-shadow: 0 8px 24px -10px rgba(94,140,74,.7);
  transition: transform 160ms var(--ease-out-strong, cubic-bezier(.23,1,.32,1)), background 160ms var(--ease-out-strong, cubic-bezier(.23,1,.32,1));
}
.pm-cta:active { background: var(--botanical); transform: scale(.97); }

.pm-section h2 { color: var(--muted); }

/* job cards + recent rows → solid panels */
.job-card {
  background: var(--slate-800);
  border: 1px solid var(--slate-line-dim);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
}
.job-card:active { box-shadow: inset 0 1px 0 rgba(255,255,255,.03), 0 4px 16px rgba(0,0,0,.4); }
.job-card .track-link { color: var(--powder); }
.job-card .svc  { color: var(--cream); }
.job-card .meta { color: var(--muted); }
.job-card .due  { color: var(--muted); }

.recent-row { border-top: 1px solid var(--slate-line-dim); }
.recent-row .body .svc  { color: var(--ink); }
.recent-row .body .meta { color: var(--muted); }
.recent-row .date { color: var(--muted); }

.pm-empty {
  background: var(--slate-800);
  border: 1px solid var(--slate-line-dim);
  color: var(--muted);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
}

.pm-fail {
  background: rgba(192,86,79,.12);
  border: 1px solid rgba(192,86,79,.35);
  color: var(--ink);
}

/* avatar — botanical with hairline */
.pm-avatar { background: var(--botanical); border: 1px solid var(--slate-line); color: #fff; }

/* wordmark chrome */
.pm-brand-dash { color: var(--cream); }
.pm-brand-dash img,
.pm-brand img { filter: brightness(0) invert(1); }

/* status badge separator so a data-driven badge reads on the slate panel */
.badge { box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); }

/* ── Skeleton shimmer — dark base, no white flash ──────────────────── */
.skel { background: var(--slate-700); }
.skel::after {
  background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,.07) 50%, transparent 100%);
}

/* ── Frosted bottom nav ────────────────────────────────────────────── */
.pm-bnav {
  background: rgba(14,18,22,.86);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-top: 1px solid var(--slate-line-dim);
  box-shadow: 0 -4px 20px rgba(0,0,0,.35);
}
.pm-bnav a { color: var(--muted); }
.pm-bnav a.active { color: var(--botanical); }

/* ═══════ Interior pages (step5 shell) ═════════════════════════════ */

.pm-page-head h1 { color: var(--cream); }
.pm-btn-pill { color: var(--powder); border-color: var(--slate-line); }
.pm-back-link { color: var(--muted); }
.pm-back-link:hover { color: var(--ink); }

/* property list cards + condition pills */
.prop-list-card {
  background: var(--slate-800);
  border: 1px solid var(--slate-line-dim);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
}
.prop-list-card:active { box-shadow: inset 0 1px 0 rgba(255,255,255,.03), 0 4px 16px rgba(0,0,0,.4); }
.prop-list-card .pname { color: var(--cream); }
.prop-list-card .paddr { color: var(--muted); }
.prop-list-card .pstats { color: var(--muted); }
.prop-list-card .pstats span:not(:last-child)::after { color: var(--muted); }
.prop-list-card .plast { color: var(--muted); }
.prop-list-card .pchev { color: var(--muted); }
.cond-none { background: var(--slate-700); color: var(--muted); }

/* modal sheet + backdrop */
.pm-backdrop { background: rgba(0,0,0,.6); }
.pm-sheet {
  background: var(--slate-800);
  border-top: 1px solid var(--slate-line);
  box-shadow: 0 -12px 40px rgba(0,0,0,.6);
}
.pm-sheet h2 { color: var(--cream); }
.pm-sheet .pm-cancel { color: var(--muted); }

/* condition gauge card */
.cond-gauge-wrap {
  background: var(--slate-800);
  border: 1px solid var(--slate-line-dim);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
}
.cond-gauge .score { color: var(--cream); }
.cond-gauge .max { color: var(--muted); }
.cond-label { color: var(--ink); }
.cond-trend { color: var(--muted); }
.cond-empty { color: var(--muted); }

/* pill tabs */
.pill-tab {
  background: var(--slate-700);
  color: var(--muted);
  border: 1px solid var(--slate-line);
  box-shadow: none;
}
.pill-tab.active { background: var(--botanical); color: #fff; border-color: var(--botanical); }

/* timeline items */
.timeline-item {
  background: var(--slate-800);
  border: 1px solid var(--slate-line-dim);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
}
.timeline-item .tdate { color: var(--cream); }
.timeline-item .tservice { color: var(--muted); }
.timeline-item .ttech { color: var(--muted); }
.timeline-item .tlink { color: var(--powder); }
.stars { color: var(--copper); }
.stars .s-off { color: var(--slate-line); }
.photo-strip img { background: var(--slate-700); }
.photo-grid a { background: var(--slate-700); }

/* before/after toggle */
.pm-toggle { background: var(--slate-700); }
.pm-toggle button { color: var(--muted); }
.pm-toggle button.on { background: var(--slate-600); color: var(--cream); box-shadow: none; }

/* checklist */
.check-section {
  background: var(--slate-800);
  border: 1px solid var(--slate-line-dim);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
}
.check-summary h3 { color: var(--cream); }
.check-prog { background: var(--slate-700); }
.check-prog .bar { background: var(--botanical); }
.check-list .done .ico { background: var(--botanical); }
.check-list .pending .ico { border: 1.5px solid var(--slate-line); }
.check-list .done span { color: var(--ink); }
.check-list .pending span { color: var(--muted); }

/* rate card */
.rate-card {
  background: var(--slate-800);
  border: 1px solid var(--slate-line-dim);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
}
.rate-card .ttl { color: var(--cream); }
.rate-card .sub { color: var(--muted); }
.rate-row button { color: var(--slate-line); }
.rate-row button.on, .rate-row button:hover { color: var(--copper); }

/* jobs search box */
.pm-search {
  background: var(--slate-700);
  border: 1px solid var(--slate-line);
  color: var(--ink);
  box-shadow: none;
}
.pm-search:focus { border-color: var(--powder); }
.pm-search::placeholder { color: var(--muted); }

/* settings */
.set-section h2 { color: var(--cream); }
.set-label { color: var(--muted); }
.set-tier-pill { background: rgba(168,197,218,.14); color: var(--powder); }
#set-card-element { background: var(--slate-700); border: 1px solid var(--slate-line); }
.set-logout { background: none; border: 1px solid var(--slate-line); color: var(--muted); }
.set-logout:hover { color: var(--ink); border-color: var(--powder); }

/* stepper */
.stepper { background: var(--slate-700); border: 1px solid var(--slate-line); }
.stepper button { color: var(--botanical); }
.stepper button:hover { background: var(--slate-600); }
.stepper input { color: var(--ink); border-left: 1px solid var(--slate-line); border-right: 1px solid var(--slate-line); }

/* calendar */
.cal-month { color: var(--cream); }
.cal-nav { border: 1px solid var(--slate-line); color: var(--ink); }
.cal-nav:active { background: var(--slate-700); }
.cal-dow { color: var(--muted); }
.cal-day:active, .cal-day.sel { background: var(--slate-700); }
.cal-day.today .cal-dn { background: var(--botanical); color: #fff; }
.cal-dn { color: var(--ink); }
.cal-dot { background: var(--botanical); }
.cal-dot-done { background: var(--copper); }
.cal-day-hd { color: var(--cream); }
.cal-empty { color: var(--muted); }

/* ── Invoices ─────────────────────────────────────────────────────── */
.inv-tab { background: var(--slate-700); color: var(--muted); border: 1px solid var(--slate-line); box-shadow: none; }
.inv-tab.active { background: var(--botanical); color: #fff; border-color: var(--botanical); }
.inv-summary .row { background: var(--slate-800); box-shadow: inset 0 1px 0 rgba(255,255,255,.03); }
.inv-summary .lbl { color: var(--muted); }
.inv-summary .amt { color: var(--ink); }
.inv-card { background: var(--slate-800); border: 1px solid var(--slate-line-dim); box-shadow: inset 0 1px 0 rgba(255,255,255,.03); }
.inv-card .num { color: var(--muted); }
.inv-card .amount { color: var(--cream); }
.inv-card .amount.paid { color: var(--muted); }
.inv-card .meta { color: var(--muted); }
.inv-card .due-line { color: var(--ink); }
.inv-card .paid-line { color: var(--botanical); }
.inv-btn-primary { background: var(--botanical); color: #fff; border: none; }
.inv-btn-outline { background: transparent; color: var(--muted); border: 1px solid var(--slate-line); }
.inv-detail-card { background: var(--slate-800); border: 1px solid var(--slate-line-dim); box-shadow: inset 0 1px 0 rgba(255,255,255,.03); }
.inv-detail-card .brand-row .left h2 { color: var(--powder); }
.inv-detail-card .brand-row .left .nb { color: var(--muted); }
.inv-detail-card .brand-row .right { color: var(--muted); }
.inv-detail-card .brand-row .right .biz { color: var(--powder); }
.inv-bill-grid h4 { color: var(--muted); }
.inv-bill-grid .v { color: var(--ink); }
.inv-prop-line { border-top: 1px solid var(--slate-line-dim); color: var(--muted); }
.inv-prop-line strong { color: var(--ink); }
.inv-items .row { border-bottom: 1px solid var(--slate-line-dim); }
.inv-items .row .desc { color: var(--ink); }
.inv-items .row .amt { color: var(--ink); }
.inv-totals .row { color: var(--muted); }
.inv-totals .row.total { border-top: 2px solid var(--slate-line); color: var(--cream); }
.inv-mia-link { color: var(--powder); }

/* ── Reduced motion ───────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .pm-cta { transition: background 160ms ease; }
  .pm-cta:active { transform: none; }
}

/* ═══════ Console (Loop 3) — brand mark + dark form controls ══════════
   The admin console pages each carry their own inline <style> block and use
   the DARK_TOKENS_CSS vars (flipped to slate in lib/htmlCore). app-dark.css is
   linked on every console page so these shared rules land everywhere. */

/* Brand wordmark mark: white PNG, sized + vertically aligned in the header. */
.brand .brand-ico,
.brand-ico {
  height: 18px; width: auto; display: inline-block;
  vertical-align: -3px; margin-right: 7px;
}
