/* Receptionline — "Blacktop Dark Glass" UI v2.
   Contract: design/blacktop-dark-glass/README.md + the prototype
   design/blacktop-dark-glass/Blacktop Dark Glass.dc.html.
   Mobile-first (390px canvas); ≥780px widens, ≥1100px is desktop. */

:root {
  /* The public site's palette (Jake, 2026-09-30: "use the same styling
     format you used for the Main page"): Apple-grey canvas, near-black
     ink, cobalt for anything you press, teal and amber as the accents,
     and liquid-glass surfaces over slow colour. Red is kept for "urgent"
     and nothing else, so it still means something. The old token names
     stay so no rule below had to move: --maroon is the action colour
     (cobalt now), --light the "positive fill". */
  --bg: #f5f5f7;
  --ink: #1d1d1f;
  --soft: #636366;                       /* 4.5:1+ on the glass */
  --faint: #6e6e73;
  --ondark: #FFFFFF;                     /* text on a cobalt or dark fill */
  --on-primary: #FFFFFF;                 /* text on the dark pill */

  --cobalt: #2563eb;
  --cobalt-deep: #1d4ed8;
  --teal: #14b8a6;
  --teal-deep: #0d9488;
  --grad-btn: linear-gradient(135deg, #2563eb, #0d9488 50%, #f59e0b);

  /* Liquid glass: frosted white over the moving colour, a light edge, a
     lit top lip and a soft shadow that lifts it off the page. */
  --glass: rgba(255,255,255,.66);        /* card */
  --glass-blur: blur(24px) saturate(180%);
  --glass-edge: rgba(255,255,255,.7);
  --glass-lip: inset 0 1px 0 rgba(255,255,255,.7);
  --surface: rgba(255,255,255,.8);       /* row card / button: readable */
  --row: rgba(255,255,255,.84);
  --track: rgba(0,0,0,.08);
  --panel: rgba(255,255,255,.82);        /* dropdown overlay */
  --chrome: rgba(255,255,255,.62);       /* header */
  --chrome-heavy: rgba(255,255,255,.72); /* bars, sheets */

  --bd: rgba(0,0,0,.08);
  --bd-strong: rgba(0,0,0,.16);
  --bd-input: rgba(0,0,0,.2);
  --hairline: rgba(0,0,0,.07);

  --maroon: #2563eb;                     /* brand action colour (cobalt) */
  --maroon-deep: #1d4ed8;
  --amber: #f59e0b;
  --amber-deep: #b45309;                 /* amber dark enough to read */
  --hot: #D14343;                        /* urgent */
  --hot-fill: #D14343;
  --hot-text: #B53A3A;
  --tint: rgba(209,67,67,.08);           /* urgent tint bg */
  --light: #2563eb;                      /* "positive fill" = cobalt */
  --light-solid: #1d4ed8;

  /* The main page's primary button: the dark pill with a teal glow. */
  --grad-primary: linear-gradient(180deg, #2c2c2e, #1d1d1f);

  --r: 18px; --r-lg: 22px; --r-badge: 10px; --pill: 980px;
  --sh-card: 0 10px 40px rgba(0,0,0,.06);
  --sh-hero: 0 24px 60px rgba(0,0,0,.10);
  --sh-press: 0 2px 8px rgba(0,0,0,.12);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { background: linear-gradient(180deg, #fbfbfd 0%, var(--bg) 45%, #eef2f7 100%) fixed; background-color: var(--bg); }
body {
  min-height: 100vh;
  /* The same type as the public site (Jake, 2026-09-27: "the font on
     everything"): the device's own SF Pro on an iPhone or Mac, Inter
     Tight everywhere else. Manrope until then. */
  font-family: -apple-system, BlinkMacSystemFont, "Inter Tight", "Segoe UI", Roboto, sans-serif;
  font-size: 20px; line-height: 1.5; color: var(--ink);
  /* Transparent so the fixed colour behind the glass shows through;
     the canvas itself is painted on <html>. */
  background: transparent;
  -webkit-font-smoothing: antialiased;
}
input, select, textarea { color-scheme: light; }
a { color: var(--maroon); font-weight: 700; text-decoration: none; }
a:hover { color: var(--maroon-deep); }
b, strong { color: var(--ink); }
.num, .tnum { font-variant-numeric: tabular-nums; }

@keyframes sheetUp { from { transform: translateY(24px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes flashIn { from { transform: translateY(-8px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* Focus — every interactive element gets the maroon ring. */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--maroon); outline-offset: 2px;
}

/* ---------------- type ---------------- */
.eyebrow {
  font-size: 15px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--soft);
}
.page-title { font-size: 34px; font-weight: 800; letter-spacing: -.01em; line-height: 1.15; }
.sec-title { font-size: 22px; font-weight: 800; }
.sub { font-size: 18px; color: var(--soft); }
.meta { font-size: 16px; font-weight: 600; color: var(--soft); font-variant-numeric: tabular-nums; }
.meta-faint { font-size: 16px; font-weight: 600; color: var(--faint); font-variant-numeric: tabular-nums; }
.hint { font-size: 16px; color: var(--faint); margin-top: 6px; line-height: 1.4; }
/* The call recording, folded under its card. Soft until opened — a row of
   players would shout; a quiet line invites. */
/* ============================================================ */
/* The access log. Reads like a ledger on purpose — a page that   */
/* has to be believed should not look designed.                  */
.chain-ok, .chain-bad { font-size: 15px; font-weight: 600; padding: 12px 14px;
  border-radius: var(--r); border: 1px solid; }
.chain-ok { color: var(--good-text, #1E7F53); border-color: rgba(30,127,83,.35);
  background: rgba(127,209,166,.08); }
.chain-bad { color: var(--hot-text); border-color: var(--maroon);
  background: rgba(37,99,235,.12); }

.audit-filters { display: flex; flex-wrap: wrap; gap: 10px; }
.audit-filters select { flex: 1 1 160px; min-width: 0; }

/* The table scrolls inside itself; the page never scrolls sideways. */
.audit-wrap { overflow-x: auto; border: 1px solid var(--bd);
  border-radius: var(--r); background: var(--surface); }
table.audit { border-collapse: collapse; width: 100%; min-width: 720px;
  font-size: 14px; }
table.audit th { text-align: left; font-size: 12px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--faint); font-weight: 700;
  padding: 10px 12px; border-bottom: 1px solid var(--bd); white-space: nowrap; }
table.audit td { padding: 9px 12px; border-bottom: 1px solid var(--bd);
  vertical-align: top; }
table.audit tr:last-child td { border-bottom: 0; }
table.audit .mono { font-family: ui-monospace, "Cascadia Mono", Menlo, monospace;
  font-size: 13px; white-space: nowrap; color: var(--soft); }
table.audit .dim { color: var(--faint); }
table.audit .role { font-size: 11px; color: var(--faint); margin-left: 6px;
  text-transform: uppercase; letter-spacing: .04em; }
.act { font-weight: 700; font-size: 13px; white-space: nowrap; }
/* Only the entries that should catch an eye get colour. Everything a normal
   working day produces stays quiet, so what is left stands out by itself. */
tr.act-listen .act { color: var(--amber-deep); }
tr.act-refused .act,
tr.act-sign-in-refused .act,
tr.act-sign-in-throttled .act { color: var(--hot-text); }
tr.act-change .act, tr.act-sign-in .act, tr.act-sign-out .act { color: var(--soft); }
tr.act-refused td,
tr.act-sign-in-refused td,
tr.act-sign-in-throttled td { background: rgba(37,99,235,.05); }

/* Site footer. Quiet by design — it is there to be found, not to be read.
   The bottom padding clears the fixed tab bar on a phone. */
.sitefoot { margin-top: 40px; padding: 18px 0 96px;
  border-top: 1px solid var(--bd); }
/* Everything left-aligned on purpose: the Ask Cora button is pinned to the
   bottom-right, and a Privacy link it sits on top of is not a Privacy link. */
.sitefoot-in { max-width: 1100px; margin: 0 auto; padding: 0 16px;
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  align-items: center; justify-content: flex-start; }
.sitefoot-who, .sitefoot-links { font-size: 13px; color: var(--faint); }
.sitefoot-links { display: flex; gap: 16px; }
.sitefoot a { color: var(--faint); text-decoration: none;
  border-bottom: 1px solid transparent; }
.sitefoot a:hover { color: var(--soft); border-bottom-color: var(--bd-strong); }
@media (min-width: 1100px) {
  .sitefoot { padding-bottom: 96px; }
}

/* The clear-off-the-list X. Sits in the card's top-right corner, quiet until
   hovered — it must never compete with Call back for a thumb. */
.row { position: relative; }
.row-x { position: absolute; top: 8px; right: 8px; z-index: 2; }
.row-x button { background: none; border: 0; color: var(--faint); cursor: pointer;
  font-size: 15px; font-weight: 700; line-height: 1; padding: 6px 8px;
  border-radius: 8px; }
.row-x button:hover { color: var(--ink); background: var(--surface); }
.row-x button:active { transform: translateY(2px); }
.row.cleared { opacity: .62; }

/* The front desk pinning a real time on a wanting-in card. */
/* Opens under Confirm rather than sitting in every card, which is what keeps
   the list one height. Its own panel, because it is a different kind of thing
   from the three contact buttons above it. */
.appt-set[hidden] { display: none; }
.appt-set {
  display: block; margin-top: 12px; padding: 12px;
  background: rgba(37,99,235,.08); border: 1px solid var(--maroon);
  border-radius: var(--r); animation: fadeIn 140ms ease-out;
}
.appt-lbl { display: block; font-size: 15px; font-weight: 700;
  color: var(--ink); margin-bottom: 8px; }
.appt-set input[type=datetime-local] { width: 100%; font-size: 16px; }
.appt-go { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.appt-go .btn { flex: 1 1 auto; width: auto; white-space: nowrap; margin: 0;
  min-width: 140px; }
.appt-set .hint { margin-top: 8px; }
.btn.act-confirm.open { background: var(--maroon); color: #fff; }

/* ---------------- the sales machine ---------------- */
/* Built for a thumb and a phone number: the number is the biggest thing on
   the card, because the whole screen exists to get a call started. */
.lead-filters { display: flex; gap: 8px; flex-wrap: wrap; }
.chip { padding: 8px 14px; border-radius: 999px; background: var(--surface);
        border: 1px solid var(--bd); font-size: 15px; font-weight: 700;
        color: var(--soft); }
.chip.on { background: var(--maroon); border-color: var(--maroon); color: #fff; }
.lead { padding: 14px 16px; }
.lead.is-hot { border-left: 4px solid var(--maroon); }
.lead-top { display: flex; justify-content: space-between; gap: 12px;
            align-items: flex-start; }
.lead-name { font-size: 19px; font-weight: 800; line-height: 1.2; }
.lead-tier { font-size: 11px; font-weight: 800; letter-spacing: .1em;
             text-transform: uppercase; padding: 4px 9px; border-radius: 999px;
             background: var(--surface); border: 1px solid var(--bd);
             color: var(--soft); white-space: nowrap; }
.lead-tier.hot { background: var(--maroon); border-color: var(--maroon);
                 color: #fff; }
/* An approved email is the one thing on the review sheet worth spotting from
   the top of a long scroll. */
.card.is-approved { border-color: var(--maroon); }
.lead-phone { display: block; margin: 10px 0 4px; font-size: 26px;
              font-weight: 800; letter-spacing: .01em; color: var(--ink);
              font-variant-numeric: tabular-nums; text-decoration: none; }
.lead-phone:hover { color: var(--maroon); }
.lead-phone.none { font-size: 17px; color: var(--faint); font-weight: 600; }
.lead-hook { font-size: 15px; color: var(--soft); line-height: 1.45;
             margin-top: 6px; font-style: italic; }
.lead-proof { font-size: 15px; line-height: 1.45; margin-top: 6px;
              color: var(--maroon); font-weight: 700; }
.lead-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.lead-actions form { display: flex; margin: 0; }
.lead-actions .btn { width: auto; margin: 0; padding: 10px 14px;
                     font-size: 15px; white-space: nowrap; }

/* The nudge that keeps the pipeline alive. */
.nudge { border: 2px solid var(--maroon); border-radius: var(--r);
         padding: 14px 16px; }
.nudge .sec-title { color: var(--maroon); }
.nudge-row { display: flex; justify-content: space-between; gap: 12px;
             align-items: baseline; padding: 7px 0;
             border-bottom: 1px solid var(--bd); }
.nudge-row:last-child { border-bottom: 0; }
.nudge-row a { font-weight: 800; font-variant-numeric: tabular-nums;
               white-space: nowrap; }
.nudge-why { font-size: 14px; color: var(--soft); }

.listen { margin-top: 10px; }
.listen > summary { list-style: none; cursor: pointer; font-size: 15px;
                    font-weight: 600; color: var(--soft); }
.listen > summary::-webkit-details-marker { display: none; }
.listen[open] > summary { color: var(--ink); }

/* ---------------- app chrome ---------------- */
.appbar {
  position: sticky; top: 0; z-index: 30;
  padding: calc(10px + env(safe-area-inset-top, 0px)) 16px 10px;
  border-bottom: 1px solid rgba(29,29,31,.16);
  background: var(--chrome); backdrop-filter: blur(16px);
  display: flex; align-items: flex-end; justify-content: space-between; gap: 8px;
}
.appbar .crumbs { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.appbar .back { font-size: 18px; font-weight: 700; color: var(--maroon); }
.appbar .brand {
  font-size: 19px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Desktop nav links live in the appbar; hidden on phones. */
.topnav { display: none; }

/* ---------------- flash ---------------- */
.flash-wrap { position: relative; z-index: 29; }
.flash-wrap > div {
  background: var(--light); color: var(--ondark);
  font-size: 19px; font-weight: 600; line-height: 1.4;
  padding: 10px 8px 10px 16px; display: flex; align-items: center;
  justify-content: space-between; gap: 8px; animation: flashIn 150ms ease-out;
}
.flash-x {
  background: none; border: none; color: var(--ondark); font-size: 26px;
  font-weight: 700; min-width: 44px; min-height: 36px; cursor: pointer; flex-shrink: 0;
}

/* ---------------- layout ---------------- */
main {
  padding: 16px 16px calc(130px + env(safe-area-inset-bottom, 0px));
  max-width: 1200px; margin: 0 auto;
}
.stack { display: flex; flex-direction: column; gap: 16px; }
.stack-sm { display: flex; flex-direction: column; gap: 8px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.split { display: flex; gap: 10px; }
.split > * { flex: 1; min-width: 0; }

/* ---------------- cards ---------------- */
.card {
  background: var(--glass); backdrop-filter: blur(14px);
  border: 1px solid var(--bd); border-radius: var(--r);
  box-shadow: var(--sh-card); padding: 16px;
}
.card.hero { border-color: var(--bd-strong); box-shadow: var(--sh-hero); padding: 20px; }
.card.flat { background: var(--surface); backdrop-filter: none; }
.card.light { background: var(--light); color: var(--ondark); backdrop-filter: none; }
.card.light .eyebrow { color: rgba(255,255,255,.6); }
.card.light .sub { color: rgba(255,255,255,.75); }
.card.callout {
  background: var(--tint); border-left: 4px solid var(--maroon);
  box-shadow: none; padding: 14px 16px;
}
.card.callout-bd { background: var(--tint); border: 2px solid var(--maroon);
  box-shadow: none; padding: 14px 16px; font-size: 19px; line-height: 1.55; }
.banner-quiet {
  background: var(--light); color: var(--ondark); border: 1px solid var(--bd);
  border-radius: var(--r); padding: 14px 16px; font-size: 19px; font-weight: 600; line-height: 1.45;
}

/* Row card — lists, calls. No blur, no shadow. */
.row {
  background: var(--row); border: 1px solid var(--bd); border-radius: var(--r);
  padding: 12px 14px;
}
.row.urgent { background: var(--tint); border-left: 4px solid var(--maroon); }
.row.dashed { border-style: dashed; border-color: rgba(29,29,31,.3); background: rgba(29,29,31,.04); }
a.row, button.row { display: block; width: 100%; text-align: left; cursor: pointer;
  font-family: inherit; color: var(--ink); }
a.row:hover, button.row:hover { background: rgba(29,29,31,.09); color: var(--ink); }
a.row:active, button.row:active { transform: translateY(2px); }
.row .r-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.row .r-name { font-size: 20px; font-weight: 700; min-width: 0; }
/* Two lines, always. A list where one card is 200px and the next is 308px
   reads as a mess even when every card is correct, because the eye is being
   asked to re-find the same information at a different height thirty times.
   Reserved so a one-line call does not collapse, clamped so a chatty one does
   not tower — the headline is written first, so what survives is the half
   that matters. */
.row .r-need {
  font-size: 18px; font-weight: 700; color: var(--ink); line-height: 1.4; margin-top: 4px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; min-height: calc(2 * 1.4em);
}
.row .r-meta { font-size: 16px; font-weight: 600; color: var(--soft); margin-top: 6px;
  font-variant-numeric: tabular-nums; }

/* ---------------- badges & chips ---------------- */
/* The row keeps its height with no badges in it, so a call with nothing to
   flag is not two pixels shorter than the thirty around it. */
.badges { display: flex; gap: 4px; flex-shrink: 0; flex-wrap: wrap;
  justify-content: flex-end; min-height: 26px; align-items: center; }
.badge {
  font-size: 14px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  padding: 2px 6px; border-radius: var(--r-badge); border: 2px solid transparent;
  display: inline-block; white-space: nowrap;
}
.badge.booked { background: var(--light-solid); color: var(--ondark); border-color: var(--light-solid); }
/* The patient answered. This is the only green on the app on purpose — it is
   the one state that means somebody outside the building said yes, and it
   should be findable down a list of thirty at a glance. */
.badge.confirmed {
  background: #1E7F53; color: #fff; border-color: #1E7F53;
  display: inline-flex; align-items: center; gap: 4px;
}
.badge.confirmed svg { width: 13px; height: 13px; }
.badge.urgent { background: var(--hot-fill); color: #fff; border-color: var(--hot-fill); }
.badge.lead { background: rgba(29,29,31,.08); color: var(--ink); border-color: rgba(29,29,31,.4); }
.badge.ah { background: var(--track); color: var(--ink); border-color: rgba(29,29,31,.35); }
.badge.cxl { background: transparent; color: var(--faint); border-color: rgba(29,29,31,.25); text-decoration: line-through; }
.badge.late { background: var(--hot-fill); color: #fff; border-color: var(--hot-fill); }
.badge.step { background: var(--surface); color: var(--ink); border: 1px solid var(--bd); }
/* status chips (lead-text / follow-up / webhook history) */
.badge.st-sent, .badge.st-replied, .badge.st-stored, .badge.st-confirmed
  { background: var(--light-solid); color: var(--ondark); border-color: var(--light-solid); }
.badge.st-skipped, .badge.st-expired, .badge.st-ignored, .badge.st-duplicate
  { background: var(--track); color: var(--ink); border-color: rgba(29,29,31,.35); }
.badge.st-stopped, .badge.st-declined { background: transparent; color: var(--hot); border-color: var(--hot); }
.badge.st-error { background: var(--hot-fill); color: #fff; border-color: var(--hot-text); }

.chip {
  font-size: 14px; font-weight: 800; letter-spacing: .06em; padding: 6px 8px;
  border-radius: var(--r-badge); background: var(--surface); color: var(--ink);
  border: 2px solid #000; display: inline-block; font-variant-numeric: tabular-nums;
}
.chip.ghost { color: var(--faint); border-style: dashed; }
.chip-big { padding: 8px 10px; font-size: 15px; border: 1px solid var(--bd); }
.chip-big.error { background: var(--hot-fill); color: #fff; border: 2px solid var(--hot-text); }
.count {
  background: var(--hot-fill); color: #fff; font-size: 15px; font-weight: 800;
  border-radius: var(--r-badge); padding: 2px 8px; font-variant-numeric: tabular-nums;
}

/* ---------------- stats ---------------- */
.stat .n { font-size: 46px; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1.1; }
.stat .n.hot { color: var(--hot-text); }
.stat .lbl { font-size: 16px; font-weight: 600; color: var(--soft); margin-top: 2px; line-height: 1.35; }
.stat .delta { font-size: 16px; font-weight: 700; margin-top: 4px; }
.stat .delta.down { color: var(--hot-text); }
.money .n { font-size: 64px; font-weight: 800; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; line-height: 1.05; margin-top: 8px; }
.rule { width: 128px; height: 6px; background: var(--maroon); margin-top: 8px; }
.rule.sm { width: 96px; }
.rule.xs { width: 64px; height: 5px; margin-top: 6px; }

/* ================================================================
   v2.1 — depth pass. The system was right and the light was missing:
   every surface sat at the same flat grey, so a screen of real work
   read as a screen of nothing. Nothing below changes a layout, a size
   or a colour token — it only puts the glass back in the glass.
   ================================================================ */

/* Ambient light. Two enormous, very faint pools — one warm at the top
   left where the eye lands, one cool low right — so the background has
   somewhere to fall away to instead of being a flat wash. Fixed, so the
   page slides over the light rather than dragging it along. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(70ch 60ch at 12% -10%, rgba(37,99,235,.13), transparent 70%),
    radial-gradient(60ch 55ch at 108% 108%, rgba(96,120,190,.10), transparent 70%);
}

/* Specular edge. Real glass catches a highlight along its top lip,
   brightest in the middle. One pseudo-element per card does what a
   border alone never could. */
.card, .row, .banner-quiet {
  position: relative;
  overflow: hidden;             /* keep the highlight inside the radius */
}
.card::before, .row::before, .banner-quiet::before {
  content: ""; position: absolute; top: 0; left: 12px; right: 12px; height: 1px;
  background: linear-gradient(90deg, transparent,
              rgba(29,29,31,.34) 30%, rgba(29,29,31,.34) 70%, transparent);
  pointer-events: none;
}
/* The light card is already bright; a white lip on white is grubby. */
.card.light::before, .banner-quiet::before { opacity: .35; }
.card.callout::before, .card.callout-bd::before { opacity: .5; }

/* A hero should feel lit from within, not just bigger. */
.card.hero {
  background:
    radial-gradient(120% 90% at 50% -20%, rgba(29,29,31,.08), transparent 60%),
    var(--glass);
}

/* Rows are the product — a list of real callers — so they get the one
   piece of motion: a hairline lift under the cursor. Phones never see
   it, which is why it is safe to make it obvious on a desktop. */
@media (hover: hover) {
  .row { transition: transform .12s ease, border-color .12s ease,
                     background-color .12s ease, box-shadow .12s ease; }
  .row:hover { transform: translateY(-1px); border-color: var(--bd-strong);
               background: rgba(29,29,31,.085);
               box-shadow: 0 6px 20px rgba(29,29,31,0.12); }

  /* Everything else a mouse can land on says so too. On a phone none of this
     exists; on a desk it is the difference between a screen you read and a
     screen you use. */
  .card { transition: border-color .12s ease, box-shadow .12s ease; }
  .card:hover { border-color: var(--bd); }

  .btn { transition: transform .1s ease, background-color .12s ease,
                     border-color .12s ease, color .12s ease; }
  .btn:hover { transform: translateY(-1px); }
  .btn:active { transform: translateY(1px); }

  .tab, .dd-row { transition: background-color .12s ease, color .12s ease; }
  .tab:hover { color: var(--ink); }
  .dd-row:hover { background: rgba(29,29,31,.08); color: var(--ink); }

  /* The sticky day heading is a control on a long diary, not a label. */
  .day-head { transition: color .12s ease; }
}

/* State at a glance. A feed where every card is identical makes the eye
   do work the colour could do for it: booked reads light, a captured
   lead reads warm, urgent already shouted. No layout shift — the bar is
   painted inside the card, not added to its box. */
.row.is-booked::after, .row.is-lead::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  pointer-events: none;
}
.row.is-booked::after { background: var(--light-solid); }
.row.is-lead::after   { background: rgba(37,99,235,.55); }
.row.cleared::after   { opacity: .3; }

/* Big numerals get a touch of dimension — the same trick a printed
   figure gets from ink sitting proud of the paper. */
.stat .n, .money .n {
  background: linear-gradient(180deg, #1d1d1f 10%, rgba(29,29,31,.78) 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.stat .n.hot, .money .n.hot {
  background: linear-gradient(180deg, #E06A6A 5%, var(--hot-text) 90%);
  -webkit-background-clip: text; background-clip: text;
}
/* A stat tile is a number and a word; give the number room to breathe
   and the tile stops looking like a box with text in it. */
.card.stat { padding: 18px 16px; }

/* Page titles get the brand's mark rather than sitting bare at the top
   of a dark screen. */
.page-title { position: relative; padding-left: 14px; }
.page-title::before {
  content: ""; position: absolute; left: 0; top: .18em; bottom: .18em;
  width: 4px; border-radius: 2px;
  background: linear-gradient(180deg, var(--maroon), var(--maroon-deep));
}

/* Empty states were a grey box saying nothing much. A dashed edge reads
   as "this will fill up", which is the truth. */
.empty { border-style: dashed; border-color: rgba(29,29,31,.22); }

/* The bar across the top is the only chrome on the page; a hairline of
   brand under it stops it dissolving into the content. */
.appbar { position: relative; }
.appbar::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(37,99,235,.45) 20%,
              rgba(37,99,235,.45) 80%, transparent);
}

/* Call-card actions. Three identical grey boxes made the owner read all
   three, every card, forever. Now the shape of the row says what to do:
   ringing back is the point of the card and wears the brand, texting is
   the ordinary fallback, and a reminder is the quiet thing you do when
   you can't do either yet. Icons carry the meaning before the words are
   read at all. */
.r-actions { gap: 6px; margin-top: 10px; }
.r-actions .btn { font-size: 17px; gap: 7px; padding: 8px 10px; }
.r-actions .ico-svg { flex-shrink: 0; opacity: .85; }
.r-actions .btn > span { white-space: nowrap; }
/* A flex item won't shrink below its content unless told to, so on a
   narrow phone the third button used to push past the card's edge and get
   clipped by the rounding. This lets the row give ground evenly instead. */
.r-actions .btn { min-width: 0; }
@media (max-width: 430px) {
  .r-actions { gap: 5px; }
  .r-actions .btn { padding: 8px 7px; gap: 6px; font-size: 16px; }
}

.btn.act-call {
  background: var(--grad-primary);
  border-color: rgba(217,140,19,.55); color: var(--on-primary); font-weight: 800;
}
.btn.act-call:hover {
  background: linear-gradient(180deg, #E8981F, #D98C13);
  border-color: var(--amber-deep); color: var(--on-primary);
}
/* Once he's actually rung them back the card should stop asking. */
.btn.act-call.done {
  background: var(--light); border-color: var(--light-solid);
  color: var(--ondark); font-weight: 800;
}
.btn.act-call.done:hover { background: var(--light-solid); color: var(--ondark); }

.btn.act-remind {
  background: transparent; border-color: var(--hairline); color: var(--soft);
  font-weight: 700;
}
.btn.act-remind:hover { background: var(--surface); border-color: var(--bd);
                        color: var(--ink); }

/* Approving a time is the one thing on the card that sends the patient a
   message, so it carries the brand colour rather than sitting quiet beside
   the calendar link it replaced. */
.btn.act-confirm {
  background: rgba(37,99,235,.16); border-color: var(--maroon);
  color: var(--maroon); font-weight: 800;
}
.btn.act-confirm:hover { background: rgba(37,99,235,.26); color: var(--ink); }

/* A mouse doesn't need a 48px target; a thumb in a bay does. Phones keep
   the contract, desktops get a tighter row that stops dominating the card. */
@media (hover: hover) and (pointer: fine) {
  .r-actions .btn { min-height: 40px; }
}

/* ---------------- buttons ---------------- */
.btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 8px 14px; width: 100%;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--bd); border-radius: var(--r);
  font-family: inherit; font-size: 19px; font-weight: 700; cursor: pointer;
  text-decoration: none; text-align: center; line-height: 1.2;
}
.btn:hover { background: rgba(29,29,31,.1); color: var(--ink); }
.btn:active { transform: translateY(2px); box-shadow: var(--sh-press); }
.btn.primary {
  min-height: 52px; background: var(--grad-primary); color: var(--on-primary);
  border: 1px solid rgba(29,29,31,.35); box-shadow: var(--sh-card); font-size: 20px;
  /* A lit top lip and a shadow pooled beneath: the difference between a
     coloured rectangle and something that looks pressable. */
  box-shadow: var(--sh-card), inset 0 1px 0 rgba(29,29,31,.28);
}
.btn.primary:hover {
  background: linear-gradient(180deg, rgba(186,54,74,.97), rgba(122,26,42,.97));
  border-color: rgba(29,29,31,.5);
}
.btn.light { background: var(--light); color: var(--ondark); }
.btn.light:hover { background: var(--light-solid); color: var(--ondark); }
.btn.danger { background: var(--surface); color: var(--maroon); border: 2px solid var(--maroon); }
.btn.danger:hover { background: var(--tint); color: var(--maroon); }
.btn.shadow { box-shadow: var(--sh-card); }
.btn.cb { color: var(--maroon); }
.btn.cb.done { background: var(--light); color: var(--ondark); }
.btn[disabled], .btn[disabled]:hover { opacity: .45; cursor: default; transform: none; box-shadow: none; }
.btn-row { display: flex; gap: 8px; }
.btn-row .grow { flex: 1.2; }
.btn-row .btn { flex: 1; padding-left: 8px; padding-right: 8px; }
.btn-row .btn.grow { flex: 1.2; }

/* ---------------- forms ---------------- */
label { display: block; font-size: 18px; font-weight: 700; margin: 14px 0 6px; }
label:first-child { margin-top: 0; }
input[type=text], input[type=tel], input[type=email], input[type=password],
input[type=number], input[type=date], input[type=time], input[type=datetime-local],
select, textarea {
  width: 100%; min-height: 48px; padding: 10px 12px;
  background: var(--glass); border: 1px solid var(--bd-input); border-radius: var(--r);
  font-size: 20px; font-family: inherit; color: var(--ink); line-height: 1.4;
}
input.missing { border: 2px solid var(--maroon); }
.needed { color: var(--hot-text); }
textarea { resize: vertical; }
select { appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--soft) 50%),
    linear-gradient(135deg, var(--soft) 50%, transparent 50%);
  background-position: calc(100% - 20px) 55%, calc(100% - 14px) 55%;
  background-size: 6px 6px; background-repeat: no-repeat; padding-right: 36px; }
select.light { background-color: var(--light); color: var(--ondark); font-weight: 700; }
.check {
  display: flex; align-items: center; gap: 12px; min-height: 48px;
  font-size: 19px; font-weight: 600; cursor: pointer; margin-top: 8px;
}
.check input[type=checkbox], .check input[type=radio]
  { width: 22px; height: 22px; accent-color: var(--maroon); flex-shrink: 0; }
.check.top { align-items: flex-start; }
.check.top input { margin-top: 4px; }
.check .c-body { display: block; }
.check .c-sub { display: block; font-size: 16px; font-weight: 400; color: var(--faint);
  margin-top: 2px; line-height: 1.4; }
.copyblock {
  background: var(--surface); border: 1px solid var(--bd); border-radius: var(--r);
  padding: 12px; font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 16px; line-height: 1.55; word-break: break-all; margin-top: 10px;
}
.msg { background: var(--surface); border: 1px solid var(--bd); border-radius: var(--r);
  padding: 12px; font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 16px; line-height: 1.55; margin-top: 8px; white-space: pre-wrap; }

/* ---------------- dropdowns (details-based) ---------------- */
details.dd { position: relative; }
details.dd > summary { list-style: none; cursor: pointer; }
details.dd > summary::-webkit-details-marker, details summary::-webkit-details-marker { display: none; }
details.dd > summary.btn { justify-content: space-between; }
details.dd .dd-panel {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 20;
  background: var(--panel); backdrop-filter: blur(18px);
  border: 1px solid var(--bd); border-radius: var(--r);
  box-shadow: var(--sh-card); padding: 8px; animation: sheetUp 160ms ease-out;
}
.dd-row {
  display: flex; width: 100%; justify-content: space-between; align-items: center;
  min-height: 48px; background: transparent; color: var(--ink); border: none;
  border-radius: 8px; padding: 0 12px; font-size: 19px; font-weight: 700;
  cursor: pointer; font-family: inherit; text-align: left; text-decoration: none;
}
.dd-row:hover { background: rgba(29,29,31,.08); color: var(--ink); }
.dd-row.active { background: var(--light); color: var(--ondark); }
.dd-row.active:hover { color: var(--ondark); }

/* Inline disclosure (Add prospect, Sent + skipped, History…) */
details.acc > summary {
  list-style: none; display: flex; align-items: center; justify-content: space-between;
  min-height: 48px; background: var(--surface); border: 1px solid var(--bd);
  border-radius: var(--r); padding: 0 14px; font-size: 19px; font-weight: 700;
  cursor: pointer; gap: 8px;
}
details.acc > summary:active { transform: translateY(2px); }
details.acc > .acc-body { padding: 8px 0 4px; display: flex; flex-direction: column; gap: 8px; }
details.acc > .acc-card { background: var(--surface); border: 1px solid var(--bd);
  border-radius: var(--r); padding: 16px; margin-top: 8px; }
details.acc.stage > summary {
  font-size: 16px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
}
details.acc.stage[open] > summary { background: var(--light); color: var(--ondark); border-color: transparent; }

/* ---------------- bottom tab bar ---------------- */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  background: var(--chrome-heavy); backdrop-filter: blur(18px);
  border-top: 1px solid rgba(29,29,31,.2);
  display: flex; padding: 0 4px calc(10px + env(safe-area-inset-bottom, 14px));
}
.tab {
  flex: 1; min-height: 54px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 3px;
  background: transparent; border: none; border-top: 3px solid transparent;
  color: var(--ink); font-size: 14px; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; cursor: pointer; padding-top: 7px;
  font-family: inherit; text-decoration: none;
}
/* Icons only on the phone bar (Jake, 2026-09-30): seven words never fitted
   at 390px. The word stays in the markup for screen readers and as the
   tooltip, so every tab still has a name. */
.tab svg { width: 24px; height: 24px; display: block; }
.tab .lbl { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
            overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.tab { position: relative; min-width: 44px; }
.tab.active svg { stroke-width: 2.4; }
.tab.active { border-top-color: var(--maroon); color: var(--maroon); }
.tab:hover { color: var(--maroon); }
.tab:active { transform: translateY(2px); }
.tab:focus-visible { outline-offset: -3px; }

/* ---------------- sheets & modal ---------------- */
.scrim {
  position: fixed; inset: 0; background: rgba(29,29,31,0.16); z-index: 40;
  animation: fadeIn 160ms ease-out; border: none; padding: 0; cursor: default;
}
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 41;
  background: var(--chrome-heavy); backdrop-filter: blur(18px);
  border-top: 1px solid rgba(29,29,31,.2);
  padding: 16px 16px calc(24px + env(safe-area-inset-bottom, 16px));
  animation: sheetUp 200ms ease-out;
}
.sheet .dd-row { background: var(--surface); border: 1px solid var(--bd);
  border-radius: var(--r); min-height: 56px; padding: 0 16px; font-size: 20px; margin-top: 8px; }
.sheet .dd-row.signout { color: var(--maroon); }

.modal-back { display: none; }
.modal-back.open { display: block; }
.modal-back .scrim-el { position: fixed; inset: 0; background: rgba(29,29,31,0.16);
  z-index: 44; animation: fadeIn 160ms ease-out; }
.modal {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  background: var(--chrome-heavy); backdrop-filter: blur(18px);
  border-top: 1px solid rgba(29,29,31,.2);
  padding: 20px 16px calc(24px + env(safe-area-inset-bottom, 16px));
  animation: sheetUp 200ms ease-out;
}
.modal .who { font-size: 26px; font-weight: 800; margin-top: 6px; }
.modal .num { font-size: 34px; font-weight: 800; font-variant-numeric: tabular-nums; margin-top: 2px; }
.modal .ctx { font-size: 18px; color: var(--soft); line-height: 1.4; margin-top: 8px; }
.modal .big-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.modal .pair { display: flex; gap: 10px; }
.modal .pair .btn { flex: 1; }
.modal .btn { min-height: 56px; }
.modal .foot { font-size: 16px; color: var(--faint); line-height: 1.45; margin-top: 12px; }
.modal .close { position: absolute; top: 14px; right: 14px; background: none; border: none;
  color: var(--ink); font-size: 26px; min-width: 44px; min-height: 44px; cursor: pointer; }

/* ---------------- charts ---------------- */
.bars { display: flex; align-items: flex-end; gap: 6px; margin-top: 14px; }
.bars .col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.bars .peak-n { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--maroon); height: 18px; }
.bars .track { width: 100%; height: 88px; display: flex; align-items: flex-end; }
.bars .bar { width: 100%; background: var(--light-solid); min-height: 4px; }
.bars .bar.peak { background: var(--maroon); }
.bars .lbl { font-size: 16px; font-weight: 600; color: var(--soft); }

.ibar-row { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.ibar-row .lbl { width: 122px; flex-shrink: 0; font-size: 16px; font-weight: 600; }
.ibar-row .track { flex: 1; height: 18px; background: var(--track); }
.ibar-row .fill { height: 100%; background: var(--light-solid); }
.ibar-row .fill.hot { background: var(--hot); }
.ibar-row .pct { width: 44px; text-align: right; font-size: 16px; font-weight: 700;
  font-variant-numeric: tabular-nums; flex-shrink: 0; }

.funnel-step .block {
  min-width: 110px; background: var(--light); color: var(--ondark);
  border: 1px solid var(--bd); border-radius: var(--r); box-shadow: var(--sh-card);
  padding: 12px 14px; font-size: 24px; font-weight: 800; font-variant-numeric: tabular-nums;
}
.funnel-step .lbl { font-size: 19px; font-weight: 700; margin-top: 8px; }
.funnel-step .desc { font-size: 16px; color: var(--soft); line-height: 1.45; margin-top: 2px; }

/* ---------------- day group headers ---------------- */
.day-head {
  position: sticky; top: 58px; z-index: 5;
  background: rgba(245,245,247,.72);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  padding: 14px 0 6px; font-size: 15px; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase;
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
}
/* How many are on this day, so the shape of the morning reads before any of
   the names do. */
.day-head .day-count {
  font-size: 13px; font-weight: 700; letter-spacing: 0; color: var(--faint);
  font-variant-numeric: tabular-nums;
}
/* Today gets the only accent on the page. Everything else stays quiet so the
   day somebody is actually working is the thing the eye lands on. */
.day-head.is-today { color: var(--maroon); }
.day-head.is-today::before {
  content: ""; position: absolute; left: -12px; top: 15px; bottom: 7px;
  width: 3px; border-radius: 2px; background: var(--maroon);
}

/* ---------------- setup wizard ---------------- */
body.setup main { padding-bottom: 170px; }
.prog { display: flex; gap: 6px; margin-top: 16px; }
.prog i { flex: 1; height: 10px; background: rgba(29,29,31,.15); border: 1px solid var(--bd); }
.prog i.done { background: var(--light-solid); }
.prog i.cur { background: var(--maroon); }
.setup-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  background: var(--chrome-heavy); backdrop-filter: blur(18px);
  border-top: 1px solid rgba(29,29,31,.2);
  padding: 14px 16px calc(20px + env(safe-area-inset-bottom, 14px));
}
.setup-bar .back-line { text-align: center; margin-top: 10px; }
.setup-bar .back-line a { font-size: 18px; }
.stepnum { font-size: 22px; font-weight: 800; color: var(--maroon); flex-shrink: 0; }
.stepline { display: flex; gap: 12px; margin-top: 12px; font-size: 20px; line-height: 1.5; }
.bignum { font-size: 34px; font-weight: 800; font-variant-numeric: tabular-nums; margin-top: 8px; }

/* ---------------- section switcher ---------------- */
.secnav-tabs { display: none; }
.sec-tab {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px;
  padding: 6px 14px; background: var(--surface); color: var(--ink);
  border: 1px solid var(--bd); border-radius: var(--r);
  font-size: 17px; font-weight: 700;
}
.sec-tab:hover { background: rgba(29,29,31,.1); color: var(--ink); }
.sec-tab.active { background: var(--light); color: var(--ondark); border-color: transparent; }
.sec-tab.active:hover { color: var(--ondark); }
@media (min-width: 780px) {
  .secnav-dd { display: none; }
  .secnav-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
}

/* The More dropdown in the tab bar opens upward. */
.tabbar details.dd { flex: 1; display: flex; }
.tabbar details.dd > summary.tab { flex: 1; width: 100%; }
.tabbar details.dd .dd-panel {
  position: fixed; left: 8px; right: 8px; top: auto;
  bottom: calc(78px + env(safe-area-inset-bottom, 14px));
  background: var(--panel);
}
.tabbar .dd-panel .dd-row { background: var(--surface); border: 1px solid var(--bd);
  border-radius: var(--r); min-height: 56px; padding: 0 16px; font-size: 20px; margin-top: 8px; }
.tabbar .dd-panel .dd-row:first-child { margin-top: 0; }
.tabbar .dd-panel .dd-row.signout { color: var(--maroon); }
/* The page you are on. The white row above outranks .dd-row.active's fill but
   not its white text, so the current page used to read white on white. */
.tabbar .dd-panel .dd-row.active { background: var(--light); color: var(--ondark);
  border-color: var(--light); }

/* Row actions inside call cards */
.r-actions { margin-top: 10px; }
.r-actions .btn { font-size: 18px; }

/* The appointment's own line under the buttons: what's booked, and the X. */
.appt-line {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--bd);
  font-size: 16px; font-weight: 700; color: var(--soft);
  font-variant-numeric: tabular-nums;
}
.appt-line.off span { color: var(--faint); }
.appt-x {
  background: transparent; color: var(--maroon); border: 0; cursor: pointer;
  font: inherit; font-weight: 800; padding: 6px 8px; margin: -6px -8px;
  border-radius: var(--r-badge); white-space: nowrap; min-height: 44px;
}
.appt-x:hover { background: var(--tint); }
.appt-line.off .appt-x { color: var(--ink); text-decoration: underline; }

/* Single-column page width on big screens; boards and grids opt out. */
.page { max-width: 760px; margin: 0 auto; }
.page-wide { max-width: 1200px; margin: 0 auto; }
.field { margin-top: 8px; }

/* ---------------- misc ---------------- */
.empty { background: var(--surface); border: 1px solid var(--bd); border-radius: var(--r);
  padding: 16px; font-size: 19px; }
.hist .when { font-size: 16px; font-weight: 600; color: var(--faint); font-variant-numeric: tabular-nums; }
.hist .what { font-size: 18px; line-height: 1.4; margin-top: 1px; }
.legal-body { font-size: 20px; line-height: 1.6; }
.legal-body h2 { font-size: 24px; font-weight: 800; margin: 22px 0 8px; }
.legal-body p, .legal-body ul { margin: 10px 0; }
.legal-body ul { padding-left: 24px; }
.legal-body .box { background: var(--tint); border: 2px solid var(--maroon); border-radius: var(--r);
  padding: 14px 16px; font-size: 19px; line-height: 1.55; margin: 14px 0; }
.login-wrap { max-width: 430px; margin: 0 auto; padding-top: 70px;
  display: flex; flex-direction: column; gap: 22px; }
.wordmark { text-align: center; font-size: 22px; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; }
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 56px; }
.pw-eye {
  position: absolute; top: 0; right: 0; bottom: 0; width: 52px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; color: var(--faint); cursor: pointer;
  border-radius: var(--r);
}
.pw-eye:active { color: var(--ink); transform: translateY(2px); }
.pw-eye:focus-visible { outline: 2px solid var(--maroon); outline-offset: -4px; }
/* [hidden] only auto-hides HTML elements, not inline SVG — cover the icons. */
.pw-eye svg[hidden] { display: none; }
.dialer { display: flex; gap: 8px; }
.dialer .btn { width: auto; flex-shrink: 0; padding: 8px 18px; }

/* ============================================================ */
/* ≥780px — tablet: top nav appears, bottom bar goes away        */
/* ============================================================ */
@media (min-width: 780px) {
  main { padding: 28px 32px 72px; }
  .tabbar { display: none; }
  .appbar { padding: 14px 32px; align-items: center; }
  .topnav { display: flex; align-items: center; gap: 22px; margin-left: 28px; flex: 1; }
  .topnav a { font-size: 16px; font-weight: 700; color: var(--ink);
    border-bottom: 3px solid transparent; padding: 6px 2px; }
  .topnav a.active { color: var(--maroon); border-bottom-color: var(--maroon); }
  .topnav a:hover { color: var(--maroon); }
  .topnav .spacer { flex: 1; }
  .topnav .who { font-size: 14px; font-weight: 600; color: var(--faint); }
  .appbar .crumbs { flex-direction: row; align-items: center; gap: 14px; }
  .modal { left: 50%; right: auto; bottom: auto; top: 50%;
    transform: translate(-50%, -50%); width: 430px; border: 1px solid var(--bd);
    border-radius: var(--r); box-shadow: var(--sh-hero); animation: fadeIn 160ms ease-out; }
  .sheet { left: auto; right: 32px; bottom: auto; top: 64px; width: 320px;
    border: 1px solid var(--bd); border-radius: var(--r); box-shadow: var(--sh-hero);
    animation: fadeIn 160ms ease-out; }
  .day-head { top: 64px; }
  .grid-4d { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
  .grid-4d.grid-2 { grid-template-columns: repeat(4, 1fr); }
  .cols-2d { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
}

/* Board container is a plain stack below desktop. */
.board { display: flex; flex-direction: column; gap: 10px; }

/* ============================================================ */
/* ≥1100px — desktop: board becomes six real columns             */
/* ============================================================ */
@media (min-width: 1100px) {
  .board { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; align-items: start; }
  .board details.acc.stage > summary { pointer-events: none; }
  .board .lost-col { opacity: .6; }
  .page-title { font-size: 38px; }

  /* Today and My Line spread into two columns. These used to be laid out
     with named grid areas, which reserve a cell whether or not the card
     that belongs in it exists — and half of them are conditional. A line
     with no audit baseline renders no money card, so the grid kept a hole
     where it would have been, and the page looked broken rather than
     empty. Auto-flow can't leave a hole: bands span the full width, and
     whatever remains falls into the next free cell. */
  .home-grid {
    display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
    align-items: start; max-width: 1180px; margin: 0 auto;
    grid-template-areas: none;
  }
  .hg-head, .hg-attn, .hg-stats, .hg-money, .hg-pipe, .hg-vol,
  .hg-latest { grid-area: auto; }

  /* Bands: the things that want the whole width, in reading order. A feed
     of call cards is always a band — squeezed into half a grid the names
     start colliding with their own badges. */
  .hg-head, .hg-stats, .hg-attn, .hg-latest { grid-column: 1 / -1; }

  /* The week's numbers read as one row, not a 2x2 block. */
  .home-grid .grid-4d {
    grid-template-columns: repeat(4, 1fr);
  }
  /* Feeds that now own the full width go two cards abreast rather than
     one enormously wide one. */
  .home-grid .hg-attn .stack-sm,
  .home-grid .hg-latest .stack-sm {
    display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
    align-items: start;
  }

  /* The rest of the pages — Calls, Calendar, This Week, the admin feeds —
     were a phone column marooned on a monitor. Give the page room and let
     card lists breathe as two columns; the home grid keeps its own
     single-column stacks. */
  .page { max-width: 1180px; }
  .stack-sm { display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
              align-items: start; }
  /* align-items:start above is right for a grid of cards of different
     heights and WRONG the moment the same class becomes a flex column —
     children shrink to their own text and the feed goes ragged. Stretch
     puts every card back on the same left and right edge. */
  .home-grid .stack-sm {
    display: flex; flex-direction: column; align-items: stretch;
  }
}

/* ============================================================ */
/* ≥1500px — a real monitor. Stop pretending it's a tablet.     */
/* ============================================================ */
@media (min-width: 1500px) {
  /* The layout above already flows; a monitor just gets more of it.
     Deliberately no grid-template-areas here — reintroducing named areas
     would reintroduce the holes they leave when an optional card is
     absent, which is the bug this pass exists to kill. */
  .page, .home-grid { max-width: 1440px; }
  .page-title { font-size: 42px; }
  /* At this width a three-up feed reads better than two very wide cards. */
  .home-grid .hg-latest .stack-sm {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ---- pipeline ---------------------------------------------------------
   One card per shop, carrying everything you act on: who, where, the number,
   and what is owed. The first pass at this was dense but drawn at 11-13px in
   grey, which fought the whole system — the token sheet sets a 16px floor on
   meta and builds everything out of glass at 12px radius. Density is worth
   having; it just has to be spoken in the same voice as the rest of the app. */

.pipe-head { display: flex; align-items: flex-end; justify-content: space-between;
             gap: 14px; flex-wrap: wrap; }
.pipe-actions { display: flex; gap: 10px; }
.late-text { color: var(--hot-text); }

/* Stage groups. Closed they read as a quiet bar; open, the summary takes the
   light fill the system uses everywhere for "this is the active one". */
.stage-block { border: 1px solid var(--bd); border-radius: var(--r);
               background: var(--glass); backdrop-filter: blur(14px);
               box-shadow: var(--sh-card); overflow: hidden; }
.stage-bar { display: flex; align-items: center; justify-content: space-between;
             gap: 12px; padding: 14px 18px; cursor: pointer; list-style: none;
             font-size: 15px; font-weight: 700; letter-spacing: .08em;
             text-transform: uppercase; color: var(--soft); }
.stage-bar::-webkit-details-marker { display: none; }
.stage-bar:active { transform: translateY(2px); }
.stage-block[open] > .stage-bar { background: var(--light);
                                  color: var(--ondark); }
.stage-count { font-size: 22px; font-weight: 800;
               font-variant-numeric: tabular-nums; }

.shop { display: grid; gap: 6px 20px; padding: 16px 18px;
        border-top: 1px solid var(--hairline);
        grid-template-columns: minmax(0, 1fr) auto; }
/* A late shop gets the urgent treatment the token sheet defines: tinted row,
   4px maroon edge. It should be findable without reading anything. */
.shop.is-late { background: var(--tint); box-shadow: inset 4px 0 0 var(--maroon); }
.shop-main { min-width: 0; }
.shop-name { font-size: 22px; font-weight: 800; line-height: 1.2;
             color: var(--ink); text-decoration: none; display: block; }
a.shop-name:hover { color: var(--maroon); }
.shop-meta { font-size: 16px; font-weight: 600; color: var(--soft);
             margin-top: 3px; }
.shop-addr { font-size: 16px; font-weight: 600; color: var(--faint);
             margin-top: 3px; }

.shop-right { display: flex; flex-direction: column; align-items: flex-end;
              gap: 6px; text-align: right; }
/* The one thing on this page that gets acted on. Tabular so a column of them
   lines up, and big enough to hit with a thumb without aiming. */
.shop-phone { font-size: 26px; font-weight: 800; letter-spacing: .01em;
              color: var(--ink); text-decoration: none; white-space: nowrap;
              font-variant-numeric: tabular-nums; }
.shop-phone:hover { color: var(--maroon); }
.shop-phone:active { transform: translateY(2px); }
.shop-next { font-size: 16px; font-weight: 600; color: var(--soft); }
.shop-next.needs { color: var(--maroon); border-bottom: 1px dashed var(--bd);
                   text-decoration: none; }

.chips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 10px; }
.chips form { display: inline-flex; }
.chip { font-size: 14px; font-weight: 800; letter-spacing: .04em;
        text-transform: uppercase; padding: 5px 12px;
        border-radius: var(--r-badge); cursor: pointer;
        background: var(--surface); border: 1px solid var(--bd);
        color: var(--soft); font-family: inherit; }
.chip:hover { border-color: var(--bd-strong); color: var(--ink); }
.chip:active { transform: translateY(2px); }
.chip.on { background: var(--hot-fill); border-color: var(--hot-fill);
           color: #fff; }

/* Jobs owed to this shop. Folded away when there is nothing outstanding, so a
   clean prospect stays two lines tall and a messy one announces itself. */
.shop-jobs { grid-column: 1 / -1; margin-top: 4px; }
.shop-jobs > summary { font-size: 16px; font-weight: 600; color: var(--faint);
                       cursor: pointer; list-style: none; padding: 6px 0; }
.shop-jobs > summary::-webkit-details-marker { display: none; }
.shop-jobs > summary:hover { color: var(--soft); }
.shop-jobs[open] > summary { color: var(--soft); }

.job { display: flex; align-items: center; gap: 12px; padding: 8px 0;
       font-size: 18px; border-top: 1px solid var(--hairline); }
.job form { display: inline-flex; }
.job-text { flex: 1; min-width: 0; color: var(--soft); }
.job-due { font-size: 16px; font-weight: 600; color: var(--faint);
           white-space: nowrap; font-variant-numeric: tabular-nums; }
.job.is-late .job-due { color: var(--hot-text); font-weight: 800; }
.tick { width: 30px; height: 30px; flex: 0 0 30px; border-radius: var(--r-badge);
        cursor: pointer; border: 1px solid var(--bd); background: transparent;
        color: var(--faint); font-size: 15px; line-height: 1; }
.tick:hover { border-color: var(--maroon); color: var(--maroon); }
.tick:active { transform: translateY(2px); }

.job-add { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.job-add input[name="text"] { flex: 1 1 200px; min-width: 0; }
.job-add input { font-size: 18px; }
.job-add .btn { flex: 0 0 auto; }
.label-picker { margin-top: 12px; }
.label-picker .chip { opacity: .7; }
.label-picker .chip:hover { opacity: 1; }

@media (max-width: 640px) {
  .shop { grid-template-columns: 1fr; }
  .shop-right { align-items: flex-start; text-align: left; margin-top: 8px; }
}

/* ---- the review sheet: one card per email, all of them open ------------
   These were <details> with only email 1 expanded, so 2 and 3 showed as two
   bare header lines and read as stray text. On the one screen whose entire
   job is "here is exactly what will land", nothing may be hidden. */
.mail { border: 1px solid var(--bd); border-radius: var(--r);
        background: var(--surface); padding: 16px 18px; margin-top: 14px; }
.mail-head { display: flex; align-items: baseline; justify-content: space-between;
             gap: 12px; flex-wrap: wrap; }
.mail-when { font-size: 15px; font-weight: 700; letter-spacing: .08em;
             text-transform: uppercase; color: var(--maroon); }
.mail-day { font-size: 16px; font-weight: 600; color: var(--faint); }
.mail-subject { font-size: 19px; font-weight: 800; color: var(--ink);
                margin-top: 10px; padding-bottom: 12px;
                border-bottom: 1px solid var(--hairline); }
.mail-body { white-space: pre-wrap; font-size: 18px; line-height: 1.55;
             color: var(--soft); margin-top: 12px; }

/* The LinkedIn assist on a lead card: quiet, one line, under the phone.
   The phone stays the loud thing — it is still the channel that converts. */
.lead-linkedin { display: inline-block; font-size: 16px; font-weight: 700;
                 color: var(--faint); text-decoration: none; margin-top: 2px; }
.lead-linkedin:hover { color: var(--maroon); }

/* ---------------- customer cards ----------------
   One card per line, sorted so the ones needing Jake sit on top. The dot
   and the left edge carry the colour; the words say why. Red = act today,
   yellow = something unfinished or drifting, green = doing its job. */
:root { --ok: #1E7F53; --warn: #C4841D; }
.cc-head { display: flex; flex-wrap: wrap; align-items: flex-end;
           justify-content: space-between; gap: 10px 16px; }
.cc-legend { display: flex; flex-wrap: wrap; gap: 8px; }
.cc-pill { display: inline-flex; align-items: center; gap: 7px; font-size: 15px;
           font-weight: 700; color: var(--soft); background: var(--surface);
           border: 1px solid var(--bd); border-radius: 999px; padding: 6px 12px; }
.cc-pill i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.cc-pill.red i { background: var(--hot); }
.cc-pill.yellow i { background: var(--warn); }
.cc-pill.green i { background: var(--ok); }
.cc-grid { display: grid; gap: 12px; }
@media (min-width: 780px) { .cc-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1200px) { .cc-grid { grid-template-columns: 1fr 1fr 1fr; } }
.cc { display: block; position: relative; color: var(--ink); text-decoration: none;
      background: var(--glass); border: 1px solid var(--bd); border-radius: var(--r);
      padding: 16px 16px 14px 18px; box-shadow: var(--sh-card); overflow: hidden; }
.cc::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px; }
.cc.red::before { background: var(--hot); }
.cc.yellow::before { background: var(--warn); }
.cc.green::before { background: var(--ok); }
.cc:hover { border-color: var(--bd-strong); color: var(--ink); text-decoration: none; }
.cc-top { display: flex; flex-direction: column; gap: 2px; }
.cc-name { display: flex; align-items: center; gap: 9px; font-size: 21px; font-weight: 800;
           line-height: 1.2; flex-wrap: wrap; }
.cc-dot { width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0; }
.cc.red .cc-dot { background: var(--hot); box-shadow: 0 0 0 4px rgba(217,83,107,.22); }
.cc.yellow .cc-dot { background: var(--warn); box-shadow: 0 0 0 4px rgba(242,181,68,.2); }
.cc.green .cc-dot { background: var(--ok); box-shadow: 0 0 0 4px rgba(79,196,142,.2); }
.cc-owner { font-size: 16px; color: var(--soft); font-weight: 600; }
.cc-nums { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 14px; }
.cc-nums div { background: var(--row); border: 1px solid var(--hairline); border-radius: 10px;
               padding: 8px 6px; text-align: center; }
.cc-nums b { display: block; font-size: 26px; font-weight: 800; line-height: 1.05; }
.cc-nums span { display: block; font-size: 12px; font-weight: 700; color: var(--faint);
                line-height: 1.15; margin-top: 3px; text-transform: uppercase; letter-spacing: .04em; }
.cc-flags { list-style: none; margin: 12px 0 0; display: flex; flex-direction: column; gap: 6px; }
.cc-flags li { font-size: 16px; font-weight: 700; padding-left: 16px; position: relative;
               line-height: 1.35; }
.cc-flags li::before { content: ""; position: absolute; left: 0; top: .5em; width: 8px; height: 8px;
                       border-radius: 50%; }
.cc-flags li.red { color: var(--hot-text); }
.cc-flags li.red::before { background: var(--hot); }
.cc-flags li.yellow { color: var(--warn); }
.cc-flags li.yellow::before { background: var(--warn); }
.cc-fine { margin-top: 12px; font-size: 16px; font-weight: 700; color: var(--ok); }
.cc-meta { margin-top: 12px; font-size: 14px; font-weight: 600; color: var(--faint);
           font-variant-numeric: tabular-nums; line-height: 1.4; }

/* On a narrow phone three actions don't fit on one line without the labels
   colliding. Ring-back keeps the whole first row; text and calendar share
   the second. */
@media (max-width: 430px) {
  .r-actions { flex-wrap: wrap; }
  .r-actions .btn { flex: 1 1 calc(50% - 6px); }
  .r-actions .btn.act-call { flex-basis: 100%; }
}

/* The message is the point of a call card; it reads in ink and bold, the
   time and number stay soft beneath it. */
.row .sub { font-weight: 700; color: var(--ink); }

/* ---- customers (the CRM in the portal) --------------------------------- */
/* Same voice as the pipeline rows: one card per person, the number loud,
   everything the owner acts on visible without a tap. */
.cust { display: grid; gap: 4px 18px; padding: 14px 16px;
        grid-template-columns: minmax(0, 1fr) auto;
        border-top: 1px solid var(--hairline); text-decoration: none;
        color: inherit; }
.cust:first-of-type { border-top: 0; }
.cust:hover { background: var(--row); }
.cust-name { font-size: 20px; font-weight: 800; color: var(--ink); line-height: 1.2; }
.cust-meta { font-size: 16px; font-weight: 600; color: var(--soft); margin-top: 2px; }
.cust-phone { font-size: 22px; font-weight: 800; color: var(--ink);
              font-variant-numeric: tabular-nums; white-space: nowrap;
              text-align: right; }
.cust-last { font-size: 15px; font-weight: 600; color: var(--faint); text-align: right; }
.cust-search { display: flex; gap: 8px; }
.cust-search input { flex: 1; min-width: 0; }
.cust-search .btn { flex: 0 0 auto; }
.field-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
              gap: 14px; }
.field-grid label { display: block; font-size: 15px; font-weight: 700;
                    color: var(--soft); margin-bottom: 5px; }
.field-grid input, .field-grid select { width: 100%; }
@media (max-width: 640px) {
  .cust { grid-template-columns: 1fr; }
  .cust-phone, .cust-last { text-align: left; }
  .field-grid { grid-template-columns: 1fr; }
}

/* ---------------- the sales pipeline: leads, calls, the queue ---------------- */
/* Who the person is, under the shop name. Same weight as the meta line so the
   row stays scannable; the shop is still the thing you read first. */
.shop-sub { font-size: 16px; font-weight: 600; color: var(--soft); margin-top: 2px; }
.shop-sub a { font-weight: 700; }
/* Temperature and LinkedIn state as small chips. Hot takes the amber that
   means "press this" everywhere else in the app — a hot lead is the one
   thing on the board that should get pressed. Cold is dashed so it reads as
   an absence rather than a state. */
.chip.temp-hot { background: var(--amber); border-color: var(--amber-deep); color: var(--on-primary); }
.chip.temp-warm { background: var(--surface); border-color: var(--amber-deep); color: var(--amber-deep); }
.chip.temp-cold { color: var(--faint); border-style: dashed; }
.chip.li { border-color: var(--maroon); color: var(--maroon); }
.chip.li.li-connected { background: var(--maroon); color: #fff; }
.chip.stage-days { color: var(--faint); }
.chip.lost-why { color: var(--hot-text); border-color: var(--hot-text); text-transform: none; letter-spacing: 0; }

/* The queue. Rows, not cards — same reasoning as the board. */
.q-row { display: flex; justify-content: space-between; align-items: center; gap: 14px;
         padding: 12px 0; border-bottom: 1px solid var(--hairline); }
.q-row:last-child { border-bottom: 0; }
.q-row.is-late .q-name { color: var(--hot-text); }
.q-main { min-width: 0; }
.q-name { font-size: 20px; font-weight: 800; color: var(--ink); display: block; line-height: 1.2; }
.q-name:hover { color: var(--maroon); }
.q-what { font-size: 15px; font-weight: 600; color: var(--soft); margin-top: 2px; }
.q-right { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.q-phone { font-size: 20px; font-weight: 800; color: var(--ink); white-space: nowrap;
           font-variant-numeric: tabular-nums; }
.q-phone:hover { color: var(--maroon); }
.q-right .btn { width: auto; min-height: 40px; padding: 0 14px; font-size: 15px; }
.q-right .tick { width: 40px; height: 40px; }

/* The call form. Outcome first and biggest, because that is the one field
   that has to be right; the rest is optional and looks it. */
.call-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.call-grid .full { grid-column: 1 / -1; }
.call-outcome { font-size: 19px; font-weight: 700; }
.calls .row .r-top b.talked { color: var(--good-text, #1E7F53); }
@media (max-width: 480px) { .call-grid { grid-template-columns: 1fr; } }

/* ---------------- inbound: everyone who pressed a button on the website ---------------- */
.inb-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
.inb-stat { padding: 14px 16px; text-decoration: none; color: inherit; }
a.inb-stat:hover { border-color: var(--maroon); }
.inb-stat.is-hot { border: 2px solid var(--maroon); }
.inb-stat .stat .n { font-size: 38px; }
.inb-mail { font-size: 15px; color: var(--soft); line-height: 1.45; }
.inb-mail a { font-weight: 700; white-space: nowrap; }
.inb-search { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.inb-search input[type=search] { flex: 1 1 240px; min-width: 0; font-size: 16px;
  padding: 10px 12px; border: 1px solid var(--bd); border-radius: var(--r-badge, 10px);
  background: var(--surface); color: var(--ink); }
.inb-search .btn { width: auto; margin: 0; padding: 10px 16px; }
.inb-clear { font-weight: 700; color: var(--soft); }
.inb-email { display: inline-block; font-size: 16px; font-weight: 700; color: var(--ink);
  margin-bottom: 4px; word-break: break-all; }
.inb-email:hover { color: var(--maroon); }
.inb-answers { display: grid; grid-template-columns: auto 1fr; gap: 4px 14px; margin: 10px 0 2px;
  padding: 10px 12px; background: var(--surface); border-radius: var(--r-badge, 10px); }
.inb-answers dt { font-size: 13px; font-weight: 800; letter-spacing: .04em; color: var(--soft);
  text-transform: uppercase; padding-top: 2px; white-space: nowrap; }
.inb-answers dd { margin: 0; font-size: 16px; line-height: 1.4; }
@media (max-width: 520px) {
  .inb-answers { grid-template-columns: 1fr; gap: 0; }
  .inb-answers dt { padding-top: 8px; }
  .inb-answers dt:first-child { padding-top: 0; }
}
/* A long badge ("Booked Tue Sep 29, 10:00 AM") drops under the name on a
   phone instead of squeezing the name into a column one word wide. */
.inb .lead-top { flex-wrap: wrap; }
.inb .lead-top .lead-id { flex: 1 1 200px; }

/* ================================================================
   Liquid glass (2026-09-30). Jake: "for the crm and the backend i need
   you to use liquid glass features in the background as well and use
   the same styling format you used for the Main page". So the app wears
   the public site's palette, type and pill buttons, and every raised
   surface is frosted glass over slow colour. This block only restyles:
   no size or layout changes, except that the header stays on screen
   while you scroll (it was always meant to; see .day-head's top).
   ================================================================ */

/* The moving colour behind everything: _ambient.html's five blobs,
   pinned to the window here instead of clipped to a hero. */
.mesh { position: fixed; inset: 0; overflow: hidden; pointer-events: none; z-index: -1; }
.mesh .blob { position: absolute; border-radius: 50%; }
.mesh .b1 { width: 70vmax; height: 70vmax; top: -24vmax; left: -22vmax;
            background: radial-gradient(circle, rgba(37,99,235,.22) 0, rgba(37,99,235,.08) 38%, transparent 66%);
            animation: glassDrift1 26s ease-in-out infinite; }
.mesh .b2 { width: 60vmax; height: 60vmax; top: 10%; right: -24vmax;
            background: radial-gradient(circle, rgba(245,158,11,.18) 0, rgba(245,158,11,.06) 38%, transparent 66%);
            animation: glassDrift2 32s ease-in-out infinite; }
.mesh .b3 { width: 64vmax; height: 64vmax; bottom: -30vmax; left: 4%;
            background: radial-gradient(circle, rgba(45,212,191,.2) 0, rgba(45,212,191,.07) 38%, transparent 66%);
            animation: glassDrift3 28s ease-in-out infinite; }
.mesh .b4 { width: 44vmax; height: 44vmax; top: -6vmax; right: 18%;
            background: radial-gradient(circle, rgba(37,99,235,.12) 0, rgba(13,148,136,.08) 40%, transparent 66%);
            animation: glassDrift4 34s ease-in-out infinite; }
.mesh .b5 { width: 40vmax; height: 40vmax; top: 46%; left: -10vmax;
            background: radial-gradient(circle, rgba(245,158,11,.12) 0, rgba(45,212,191,.08) 40%, transparent 66%);
            animation: glassDrift5 24s ease-in-out infinite; }
@keyframes glassDrift1 { 50% { transform: translate(6vw, 5vh) scale(1.08); } }
@keyframes glassDrift2 { 50% { transform: translate(-6vw, 4vh) scale(.94); } }
@keyframes glassDrift3 { 50% { transform: translate(5vw, -5vh) scale(1.1); } }
@keyframes glassDrift4 { 50% { transform: translate(-4vw, 6vh) scale(1.05); } }
@keyframes glassDrift5 { 50% { transform: translate(4vw, -4vh) scale(.92); } }

/* Every raised surface is the same glass. */
.card, .stage-block, .cc, details.dd .dd-panel {
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lip), var(--sh-card);
}
details.dd .dd-panel, .tabbar details.dd .dd-panel { background: var(--panel); border-radius: var(--r); }
.card.hero { border-color: var(--glass-edge); box-shadow: var(--glass-lip), var(--sh-hero); }
.card.callout, .card.callout-bd { background: linear-gradient(var(--tint), var(--tint)), var(--glass); }
.card.callout { border-left: 4px solid var(--maroon); }
.card.flat { background: var(--surface); }
@media (hover: hover) { .card:hover { border-color: rgba(255,255,255,.95); } }
/* The top lip catches light instead of casting a line. */
.card::before, .row::before, .banner-quiet::before {
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.95) 30%,
              rgba(255,255,255,.95) 70%, transparent);
}

.appbar {
  position: sticky; top: 0;
  background: var(--chrome);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lip), 0 8px 30px rgba(0,0,0,.05);
}
.tabbar, .sheet, .modal, .setup-bar {
  background: var(--chrome-heavy);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  border-top: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lip), 0 -8px 30px rgba(0,0,0,.06);
}
.scrim, .modal-back .scrim-el { -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
@media (min-width: 780px) {
  .modal, .sheet { border: 1px solid var(--glass-edge); border-radius: var(--r-lg);
                   box-shadow: var(--glass-lip), var(--sh-hero); }
}
.day-head { padding-left: 4px; padding-right: 4px; }

/* Lists and tables stay nearly opaque: glass is for the frame, and a
   caller's name should never sit on moving colour. */
.row:hover, .cust:hover { background: rgba(255,255,255,.96); }
@media (hover: hover) { .row:hover { background: rgba(255,255,255,.96); box-shadow: 0 8px 24px rgba(0,0,0,.08); } }
.audit-wrap { background: rgba(255,255,255,.92); }
input[type=text], input[type=tel], input[type=email], input[type=password],
input[type=number], input[type=date], input[type=time], input[type=datetime-local],
select, textarea { background-color: rgba(255,255,255,.86); border-radius: 14px; }
select.light { background-color: var(--light); }

/* Buttons are the main page's pills. The primary is its dark pill with
   the teal glow; everything else is a light glass pill. */
.btn, .sec-tab, details.acc > summary { border-radius: var(--pill); }
.dd-row { border-radius: 12px; }
.pipe-actions .btn { width: auto; white-space: nowrap; padding-left: 18px; padding-right: 18px; }
.btn:hover, .sec-tab:hover { background: rgba(255,255,255,.96); border-color: var(--bd-strong); }
.btn.primary, .btn.act-call {
  background: var(--grad-primary); color: var(--on-primary);
  border: 1px solid rgba(255,255,255,.1);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 0 24px rgba(13,148,136,.3), 0 8px 24px rgba(0,0,0,.12);
}
.btn.primary:hover, .btn.act-call:hover {
  background: #2a2a2d; color: var(--on-primary); border-color: rgba(255,255,255,.1);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 0 30px rgba(13,148,136,.45), 0 10px 28px rgba(0,0,0,.16);
}
.btn.light:hover, .btn.act-call.done, .btn.act-call.done:hover { background: var(--light-solid); color: var(--ondark); border-color: transparent; box-shadow: none; }
.btn.danger:hover { background: rgba(209,67,67,.08); }
.btn.act-confirm { background: rgba(37,99,235,.12); color: var(--maroon-deep); }
.chip.temp-hot { color: var(--ink); }
.page-title::before { background: var(--grad-btn); }

/* Focus: a cobalt ring you can see on glass, white fill or dark pill. */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid var(--cobalt); outline-offset: 2px;
}

/* No backdrop-filter, or the viewer asked for less transparency: solid
   panels, same layout. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root { --glass: #fff; --surface: #fff; --row: #fff; --panel: #fff;
          --chrome: rgba(250,250,252,.98); --chrome-heavy: #fafafc; }
  .day-head { background: rgba(245,245,247,.97); }
}
@media (prefers-reduced-transparency: reduce) {
  :root { --glass: #fff; --surface: #fff; --row: #fff; --panel: #fff;
          --chrome: rgba(250,250,252,.98); --chrome-heavy: #fafafc; }
}
/* Reduced motion: the colour stays, it just stops drifting. */
@media (prefers-reduced-motion: reduce) {
  .mesh .blob { animation: none !important; }
}
