diff --git a/apps/admin/src/components/map/leaflet-map.tsx b/apps/admin/src/components/map/leaflet-map.tsx index 90458cf..94349c4 100644 --- a/apps/admin/src/components/map/leaflet-map.tsx +++ b/apps/admin/src/components/map/leaflet-map.tsx @@ -58,9 +58,9 @@ const GLYPHS: Record = { "M12 9 a2 2 0 0 1 3 -1.3 a2 2 0 0 1 0.5 3 L12 14 L8.5 10.7 a2 2 0 0 1 0.5 -3 A2 2 0 0 1 12 9 Z M4 13 v5 a1 1 0 0 0 1 1 h2 v-6 Z M20 13 v5 a1 1 0 0 1 -1 1 h-2 v-6 Z", } const PIN_FILL: Record = { - routed: "#8A8378", + routed: "var(--ink-3)", needs: "#E5564B", - event: "#E5AE1C", + event: "var(--sun-600)", "event-volunteer": "#5B8C6E", } // Event kinds own their fill and glyph; `draft` never overrides them. @@ -82,8 +82,8 @@ function pinIcon( const html = `
` + `` + - `` + - `` + + `` + + `` + `` + `
` return L.divIcon({ diff --git a/apps/admin/src/features/analytics/analytics-page.tsx b/apps/admin/src/features/analytics/analytics-page.tsx index 2d14fe9..8650e04 100644 --- a/apps/admin/src/features/analytics/analytics-page.tsx +++ b/apps/admin/src/features/analytics/analytics-page.tsx @@ -307,7 +307,7 @@ export function AnalyticsPage(_props: SectionPageProps) { return (
{d.rows.map((r) => ( -
+
{REPORT_CATEGORY_LABELS[r.cat]} diff --git a/apps/admin/src/features/home/home-page.tsx b/apps/admin/src/features/home/home-page.tsx index efe502a..3c34e7a 100644 --- a/apps/admin/src/features/home/home-page.tsx +++ b/apps/admin/src/features/home/home-page.tsx @@ -544,7 +544,7 @@ function SectionTile({ label={`Pins per week, last ${s.spark.length} weeks: ${s.spark.join(", ")}`} /> ) : ( -
No data yet
+
No data yet
))}
{s.metrics && ( diff --git a/apps/admin/src/features/mail/mail-page.tsx b/apps/admin/src/features/mail/mail-page.tsx index 37783d2..a5f0dc6 100644 --- a/apps/admin/src/features/mail/mail-page.tsx +++ b/apps/admin/src/features/mail/mail-page.tsx @@ -160,7 +160,7 @@ function ComposeEditor({ onClose, onSend, pending }: ComposeModalProps) {
)} -
+
{page.seo.title ?? title}
{page.seo.description &&
{page.seo.description}
}
diff --git a/apps/admin/src/styles/admin.css b/apps/admin/src/styles/admin.css index 47fa20f..cf0a83a 100644 --- a/apps/admin/src/styles/admin.css +++ b/apps/admin/src/styles/admin.css @@ -1,12 +1,7 @@ -/* ========================================================================= - PinIt Admin Dashboard - Operations - Linear-density x PinIt's warm cream paper. Responsive desktop -> mobile. - ========================================================================= */ @import url('./colors-and-type.css'); * { box-sizing: border-box; } -html, body, #root { margin: 0; padding: 0; } -html, body { min-height: 100%; } +html, body { margin: 0; padding: 0; min-height: 100%; } /* Always reserve the vertical scrollbar gutter so the document never re-centers .main when a page's height crosses the viewport (e.g. switching the Mail folder Outreach -> Inbox drops the deliverability strip): without this the scrollbar appears/disappears and the centered content jumps a @@ -14,11 +9,7 @@ html, body { min-height: 100%; } html { scrollbar-gutter: stable; } body { - font-family: var(--font-body); font-size: var(--fs-14); - color: var(--ink); - background: var(--paper); - -webkit-font-smoothing: antialiased; font-feature-settings: "ss01" 1, "cv11" 1; } @@ -26,339 +17,17 @@ button { font-family: inherit; cursor: pointer; } button:focus-visible { outline: none; box-shadow: var(--ring); } :focus-visible { outline: none; } -/* -- Design knobs ---------------------------------------- */ -:root { - --sidebar-w: 220px; - --sidebar-w-collapsed: 56px; - --topbar-h: 52px; - --gutter: 16px; - --card-radius: 12px; - --row-pad-y: 11px; - --row-pad-x: 14px; -} -:root[data-density="compact"] { - --gutter: 10px; - --row-pad-y: 7px; - --row-pad-x: 11px; -} - -/* Responsive widths */ -.desktop-only { } -.mobile-only { display: none !important; } -@media (max-width: 880px) { - .desktop-only { display: none !important; } - .mobile-only { display: inline-flex !important; } -} - -/* --------------------------------------------------------- - App shell - --------------------------------------------------------- */ -.shell { - display: grid; - grid-template-columns: var(--sidebar-w) 1fr; - grid-template-rows: var(--topbar-h) 1fr; - min-height: 100vh; - background: var(--paper); -} -.shell.collapsed { --sidebar-w: var(--sidebar-w-collapsed); } - -@media (max-width: 880px) { - .shell { - grid-template-columns: 1fr; - grid-template-rows: var(--topbar-h) 1fr; - } -} - -/* --------------------------------------------------------- - Top bar - --------------------------------------------------------- */ -.topbar { - grid-column: 1 / -1; - display: flex; - align-items: center; - height: var(--topbar-h); - padding: 0 14px; - background: rgba(251,247,240,0.92); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border-bottom: 1px solid var(--border-soft); - gap: 10px; - z-index: 30; - position: sticky; - top: 0; -} -.topbar .logo { - display: flex; - align-items: center; - gap: 8px; - font-family: var(--font-display); - font-weight: 700; - letter-spacing: -0.01em; - font-size: 15px; - flex-shrink: 0; -} -.topbar .logo img { width: 22px; height: 22px; } -.topbar .logo-tag { - font-family: var(--font-body); - font-size: 10.5px; - font-weight: 700; - letter-spacing: 0.05em; - text-transform: uppercase; - color: var(--ink-3); - background: var(--paper-2); - border: 1px solid var(--border-soft); - padding: 1px 6px; - border-radius: 5px; - margin-left: 2px; -} -.topbar .crumbs { - display: flex; - align-items: center; - gap: 6px; - font-size: 13px; - color: var(--ink-2); - font-weight: 600; - margin-left: 4px; -} -.topbar .crumbs .here { - color: var(--ink); - font-family: var(--font-display); - font-size: 14px; - letter-spacing: -0.01em; -} -.topbar .spacer { flex: 1; } - -.topbar .cmdk { - display: flex; - align-items: center; - gap: 8px; - padding: 6px 8px 6px 10px; - background: #fff; - border: 1px solid var(--border-soft); - border-radius: 8px; - font-size: 12.5px; - color: var(--ink-3); - width: 300px; - cursor: text; - transition: border-color 120ms var(--ease-out); -} -.topbar .cmdk:hover { border-color: var(--border); } -.topbar .cmdk .kbd { - margin-left: auto; - font-family: var(--font-mono); - font-size: 10.5px; - color: var(--ink-3); - background: var(--paper-2); - border: 1px solid var(--border-soft); - border-bottom-width: 1.5px; - border-radius: 4px; - padding: 1px 5px; -} -@media (max-width: 640px) { - .topbar .cmdk { width: 38px; padding: 6px; justify-content: center; } - .topbar .cmdk .cmdk-placeholder, - .topbar .cmdk .kbd { display: none; } -} - -.topbar .iconbtn { - width: 32px; height: 32px; - display: inline-flex; - align-items: center; - justify-content: center; - border-radius: 7px; - border: 1px solid transparent; - background: transparent; - color: var(--ink-2); - position: relative; - transition: background 120ms var(--ease-out), color 120ms var(--ease-out); -} -.topbar .iconbtn:hover { background: var(--paper-2); color: var(--ink); } -.topbar .iconbtn .pip { - position: absolute; - top: 7px; right: 7px; - width: 6px; height: 6px; - background: var(--bloom); - border-radius: 50%; - box-shadow: 0 0 0 2px var(--paper); -} -.topbar .avatar { - width: 28px; height: 28px; - border-radius: 50%; - background: linear-gradient(135deg, var(--lilac) 0%, var(--bloom) 100%); - color: #fff; - display: inline-flex; - align-items: center; - justify-content: center; - font-weight: 700; - font-size: 11px; - flex-shrink: 0; - border: 2px solid var(--paper); - box-shadow: var(--shadow-1); -} - -/* --------------------------------------------------------- - Sidebar - --------------------------------------------------------- */ -.sidebar-wrap { - position: sticky; - top: var(--topbar-h); - height: calc(100vh - var(--topbar-h)); - align-self: start; - z-index: 10; -} -.sidebar { - border-right: 1px solid var(--border-soft); - padding: 12px 10px; - background: var(--paper); - display: flex; - flex-direction: column; - gap: 2px; - font-size: 13px; - height: 100%; - overflow-y: auto; -} -.sidebar-divider { - height: 1px; - background: var(--border-soft); - margin: 12px 4px 8px; -} -.sidebar .nav { - display: flex; - align-items: center; - gap: 10px; - padding: 7px 10px; - border-radius: 7px; - color: var(--ink-2); - font-weight: 600; - font-size: 13px; - cursor: pointer; - transition: background 120ms var(--ease-out), color 120ms var(--ease-out); - position: relative; - border: 1px solid transparent; - background: transparent; - width: 100%; - text-align: left; -} -.sidebar .nav:hover { background: var(--paper-2); color: var(--ink); } -.sidebar .nav.active { - background: #fff; - color: var(--ink); - box-shadow: var(--shadow-1); - border-color: var(--border-soft); -} -.sidebar .nav.active::before { - content: ""; - position: absolute; - left: -10px; - top: 8px; bottom: 8px; - width: 2.5px; - border-radius: 0 2px 2px 0; - background: var(--bloom); -} -.sidebar .nav svg { - width: 16px; height: 16px; - flex-shrink: 0; - color: var(--ink-3); - transition: color 120ms var(--ease-out); -} -.sidebar .nav .label { - flex: 1; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.sidebar .nav.active svg { color: var(--bloom); } -.sidebar .nav .count { - margin-left: auto; - font-family: var(--font-mono); - font-size: 11px; - color: var(--ink-3); - background: var(--paper-2); - border: 1px solid var(--border-soft); - border-radius: 5px; - padding: 0 5px; - font-feature-settings: "tnum" 1; - font-weight: 600; -} -.sidebar .nav .count.hot { - background: var(--bloom-50); - color: var(--bloom-700); - border-color: color-mix(in oklab, var(--bloom) 22%, transparent); -} - -.sidebar .me { - margin-top: auto; - display: flex; - gap: 9px; - align-items: center; - padding: 10px 8px 4px; - border-top: 1px solid var(--border-soft); - margin-top: 16px; -} -.sidebar .me .who { - font-size: 12.5px; - font-weight: 700; - line-height: 1.1; - white-space: nowrap; -} -.sidebar .me .me-text { flex: 1; min-width: 0; } - -/* Sidebar collapsed (desktop only) */ -.shell.collapsed .sidebar .nav .label, -.shell.collapsed .sidebar .nav .count, -.shell.collapsed .sidebar .me .me-text { - display: none; -} -.shell.collapsed .sidebar .nav { justify-content: center; padding: 8px; } -.shell.collapsed .sidebar .me { justify-content: center; } -.shell.collapsed .topbar .logo .wd, -.shell.collapsed .topbar .logo-tag { display: none; } - -/* Mobile sidebar = drawer */ -.sidebar-backdrop { - position: fixed; - inset: 0; - background: rgba(26,23,20,0.32); - backdrop-filter: blur(2px); - z-index: 55; - opacity: 0; - pointer-events: none; - transition: opacity 240ms var(--ease-out); - display: none; -} -.sidebar-backdrop.open { opacity: 1; pointer-events: auto; } - -@media (max-width: 880px) { - .sidebar-wrap { - position: fixed; - top: 0; - left: 0; - height: 100vh; - width: 264px; - z-index: 60; - transform: translateX(-100%); - transition: transform 280ms var(--ease-out); - } - .sidebar-wrap .sidebar { - padding-top: calc(var(--topbar-h) + 8px); - box-shadow: var(--shadow-3); - } - .sidebar-wrap.mobile-open { transform: translateX(0); } - .sidebar-backdrop { display: block; } -} - -/* --------------------------------------------------------- - Main work area - --------------------------------------------------------- */ .main { - padding: var(--gutter); display: flex; flex-direction: column; gap: var(--gutter); min-width: 0; + max-width: 1600px; + margin: 0 auto; + width: 100%; + padding: var(--gutter) clamp(22px, 2.4vw, 56px) 72px; } -/* Page header */ .page-head { display: flex; align-items: flex-start; @@ -396,38 +65,8 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } font-feature-settings: "tnum" 1; } -/* Hero + map row */ -.hero-row { - display: grid; - grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); - gap: var(--gutter); - align-items: start; -} -@media (max-width: 1180px) { - .hero-row { grid-template-columns: 1fr; } -} - -/* Queue + rail row */ -.work-row { - display: grid; - grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr); - gap: var(--gutter); - align-items: start; -} -.work-rail { - display: flex; - flex-direction: column; - gap: var(--gutter); -} -@media (max-width: 980px) { - .work-row { grid-template-columns: 1fr; } -} - -/* --------------------------------------------------------- - Card primitive - --------------------------------------------------------- */ .card { - background: #fff; + background: var(--card); border-radius: var(--card-radius); border: 1px solid var(--border-soft); box-shadow: var(--shadow-1); @@ -481,27 +120,10 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } .card .card-head .head-action svg { width: 12px; height: 12px; flex-shrink: 0; } .card .card-head .head-action:hover { background: var(--paper-2); color: var(--ink); } -.live-inline-dot { - width: 7px; height: 7px; - border-radius: 50%; - background: var(--bloom); - box-shadow: 0 0 0 0 color-mix(in oklab, var(--bloom) 60%, transparent); - animation: pulseSoft 2.2s ease-in-out infinite; - display: inline-block; - flex-shrink: 0; -} -@keyframes pulseSoft { - 0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--bloom) 60%, transparent); } - 50% { box-shadow: 0 0 0 6px color-mix(in oklab, var(--bloom) 0%, transparent); } -} - -/* --------------------------------------------------------- - Status strip - --------------------------------------------------------- */ .statusstrip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); - background: #fff; + background: var(--card); border: 1px solid var(--border-soft); border-radius: var(--card-radius); overflow: hidden; @@ -561,7 +183,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } border-radius: 0 2px 2px 0; } .statcell.tone-ok .statcell-hot { color: var(--moss-700); } -.statcell.tone-info .statcell-hot { color: var(--sky-700); } @media (max-width: 880px) { .statusstrip { @@ -573,200 +194,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } } } -/* --------------------------------------------------------- - Up next hero - --------------------------------------------------------- */ -.upnext { - background: - linear-gradient(135deg, var(--bloom-50) 0%, transparent 45%), - #fff; - border: 1px solid color-mix(in oklab, var(--bloom) 18%, transparent); - border-radius: var(--card-radius); - padding: 18px 20px 20px; - box-shadow: var(--shadow-2); - position: relative; - overflow: hidden; -} -.upnext::before { - content: ""; - position: absolute; - inset: 0; - background-image: url('/ds/topo-pattern.svg'); - background-size: 280px; - opacity: 0.05; - pointer-events: none; -} -.upnext-meta { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 12px; - flex-wrap: wrap; - gap: 8px; -} -.upnext-eyebrow { - display: inline-flex; - align-items: center; - gap: 7px; - font-size: 11px; - font-weight: 700; - letter-spacing: 0.07em; - text-transform: uppercase; - color: var(--bloom-700); - white-space: nowrap; - flex-shrink: 0; -} -.upnext-pulse { - width: 7px; height: 7px; - background: var(--bloom); - border-radius: 50%; - animation: pulseSoft 2.2s ease-in-out infinite; - box-shadow: 0 0 0 0 color-mix(in oklab, var(--bloom) 60%, transparent); -} -.upnext-because { - font-size: 12px; - color: var(--ink-3); - font-weight: 500; -} - -.upnext-grid { - display: grid; - grid-template-columns: minmax(0, 1fr) 180px; - gap: 18px; - align-items: start; - position: relative; -} -@media (max-width: 720px) { - .upnext-grid { grid-template-columns: 1fr; } -} - -.upnext-main { min-width: 0; } - -.upnext-titles { - display: flex; - align-items: flex-start; - gap: 12px; - margin-bottom: 10px; -} -.upnext-pin { - width: 44px; height: 44px; - border-radius: 10px; - background: #fff; - border: 1px solid var(--border-soft); - padding: 5px; - flex-shrink: 0; - box-shadow: var(--shadow-1); -} -.upnext-pin img { width: 100%; height: 100%; object-fit: contain; } -.upnext-title-text { flex: 1; min-width: 0; } -.upnext-title-text h2 { - font-family: var(--font-display); - font-weight: 700; - font-size: 24px; - letter-spacing: -0.025em; - line-height: 1.05; - margin: 0 0 5px; - color: var(--ink); - word-break: break-word; -} -.upnext-sub { - font-size: 13px; - color: var(--ink-3); - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 4px 6px; - line-height: 1.4; -} -.upnext-sub > * { white-space: nowrap; } -.upnext-sub .strong { color: var(--ink); font-weight: 700; } -.upnext-sub .sep { color: var(--ink-4); } - -.upnext-slabadge { - display: inline-flex; - align-items: center; - gap: 5px; - background: var(--bloom); - color: #fff; - border-radius: 999px; - padding: 3px 10px 3px 9px; - font-size: 11px; - font-weight: 700; - letter-spacing: 0.02em; - white-space: nowrap; - flex-shrink: 0; - box-shadow: 0 1px 3px rgba(229,95,80,0.35); -} - -.upnext-desc { - font-size: 13.5px; - color: var(--ink-2); - line-height: 1.5; - margin: 4px 0 16px; - text-wrap: pretty; - max-width: 60ch; -} - -.upnext-cta-row { - display: flex; - align-items: center; - gap: 8px; - flex-wrap: wrap; -} -.upnext-hint { - font-size: 12px; - color: var(--ink-3); - margin-left: 6px; - white-space: nowrap; -} - -.upnext-side { - display: flex; - flex-direction: column; - gap: 14px; -} -.upnext-stat { - background: transparent; - border: none; - border-radius: 0; - padding: 0; -} -.upnext-stat + .upnext-stat { - border-top: 1px solid var(--border-soft); - padding-top: 14px; -} -.upnext-stat-label { - font-size: 10.5px; - font-weight: 700; - letter-spacing: 0.06em; - text-transform: uppercase; - color: var(--ink-3); - margin-bottom: 4px; -} -.upnext-stat-num { - font-family: var(--font-display); - font-variation-settings: "opsz" 38, "wdth" 88; - font-weight: 700; - font-size: 26px; - letter-spacing: -0.022em; - line-height: 1; - color: var(--ink); - font-feature-settings: "tnum" 1, "lnum" 1; -} -.upnext-stat-num.small { - font-size: 18px; - font-variation-settings: "opsz" 24, "wdth" 100; - letter-spacing: -0.015em; -} -.upnext-stat-foot { - font-size: 11px; - color: var(--ink-3); - margin-top: 4px; -} - -/* --------------------------------------------------------- - Live US activity - --------------------------------------------------------- */ .live-map-card { min-height: 360px; } .live-map { position: relative; @@ -781,90 +208,9 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } background: var(--paper-2); } -/* Leaflet brand pin (divIcon) */ -.pi-map-pin-wrap { background: none !important; border: none !important; } -.pi-map-pin { - position: relative; - aspect-ratio: 1 / 1.25; - transform-origin: 50% 100%; - filter: drop-shadow(0 3px 5px var(--pin-glow, rgba(26,23,20,0.3))); - transition: transform 140ms var(--ease-spring); -} -.pi-map-pin img { - width: 100%; - height: 100%; - display: block; - object-fit: contain; -} -.pi-map-pin:hover { transform: translateY(-2px) scale(1.06); } -.pi-map-pin.is-active { transform: translateY(-2px) scale(1.08); z-index: 5; } -.pi-map-pin .pi-map-count { - position: absolute; - top: -5px; right: -7px; - min-width: 16px; - height: 16px; - padding: 0 4px; - background: #fff; - border: 1px solid var(--border); - border-radius: 999px; - font-family: var(--font-mono); - font-size: 10px; - font-weight: 700; - color: var(--ink); - display: flex; - align-items: center; - justify-content: center; - box-shadow: var(--shadow-1); - font-feature-settings: "tnum" 1; -} -/* draft = unregistered jurisdiction -> dashed coral ring + ping */ -.pi-map-pin.is-draft::before { - content: ""; - position: absolute; - left: 50%; - top: 38%; - width: 30px; height: 30px; - transform: translate(-50%, -50%); - border: 2px dashed var(--bloom); - border-radius: 50%; - opacity: 0.9; -} -.pi-map-pin.is-draft::after { - content: ""; - position: absolute; - left: 50%; - top: 38%; - width: 30px; height: 30px; - transform: translate(-50%, -50%); - border-radius: 50%; - background: var(--bloom); - opacity: 0.18; - animation: draftPing 2.4s var(--ease-out) infinite; -} -@keyframes draftPing { - 0% { transform: translate(-50%, -50%) scale(0.7); opacity: 0.25; } - 100% { transform: translate(-50%, -50%) scale(2.2); opacity: 0; } -} -.pi-map-pin.is-draft .pi-map-count { - background: var(--bloom-50); - border-color: color-mix(in oklab, var(--bloom) 32%, transparent); - color: var(--bloom-700); -} - -/* user dot */ -.pi-map-userdot { - width: 18px; height: 18px; - border-radius: 50%; - background: var(--sky); - border: 3px solid #fff; - box-shadow: var(--shadow-2), 0 0 0 0 color-mix(in oklab, var(--sky) 55%, transparent); - animation: pulseSoft 2.2s ease-in-out infinite; -} - -/* Leaflet tooltip override -> on-brand */ .pi-map-tip.leaflet-tooltip { background: var(--ink); - color: #fff; + color: var(--fg-on-color); border: none; border-radius: 7px; padding: 5px 9px; @@ -882,13 +228,12 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } } .leaflet-control-attribution a { color: var(--ink-2) !important; } .leaflet-bar a { - background: #fff !important; + background: var(--card) !important; color: var(--ink-2) !important; border-color: var(--border-soft) !important; } .leaflet-bar a:hover { background: var(--paper-2) !important; } -/* Legend + active card overlays */ .live-map .map-legend { position: absolute; bottom: 10px; left: 12px; @@ -915,11 +260,10 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } width: 8px; height: 8px; border-radius: 50%; } -.live-map .map-legend .pin-routed { background: #8A8378; } +.live-map .map-legend .pin-routed { background: var(--ink-3); } .live-map .map-legend .pin-needs { background: #E5564B; } -.live-map .map-legend .pin-events { background: #E5AE1C; } +.live-map .map-legend .pin-events { background: var(--sun-600); } -/* Map markers - report-type glyph kept, only color changes */ .pi-pin2-wrap { background: none; border: none; } .pi-pin2 { display: block; filter: drop-shadow(0 2px 3px rgba(26,23,20,0.3)); transition: transform 120ms var(--ease-out); } .pi-pin2 svg { display: block; } @@ -948,75 +292,17 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } display: flex; align-items: center; justify-content: center; - color: #fff; + color: var(--fg-on-color); } -.map-active-card .mac-pin.is-routed { background: #8A8378; } +.map-active-card .mac-pin.is-routed { background: var(--ink-3); } .map-active-card .mac-pin.is-needs { background: #E5564B; } -.map-active-card .mac-pin.is-event { background: #E5AE1C; } -.map-active-card .mac-pin img { width: 100%; height: 100%; object-fit: contain; } +.map-active-card .mac-pin.is-event { background: var(--sun-600); } .map-active-card .mac-body { min-width: 0; flex: 1; } .map-active-card .mac-title { font-weight: 700; font-size: 13px; color: var(--ink); } .map-active-card .mac-sub { font-size: 11.5px; color: var(--ink-3); display: flex; gap: 5px; align-items: center; margin-top: 1px; } .map-active-card .mac-sub .sep { color: var(--ink-4); } .card-head .ha-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; } -/* --------------------------------------------------------- - Queue tabs + rows - --------------------------------------------------------- */ -.queue-card { min-height: 380px; } -.queue-tabs { - padding-left: 6px !important; - padding-right: 8px !important; - padding-top: 6px !important; - padding-bottom: 6px !important; -} -.qtab { - display: inline-flex; - align-items: center; - gap: 7px; - padding: 7px 12px 7px 10px; - border-radius: 7px; - background: transparent; - border: 1px solid transparent; - font-size: 13px; - font-weight: 700; - color: var(--ink-3); - font-family: var(--font-body); - transition: background 120ms var(--ease-out), color 120ms var(--ease-out); - white-space: nowrap; -} -.qtab:hover { background: var(--paper-2); color: var(--ink-2); } -.qtab.active { - background: var(--paper-2); - color: var(--ink); - border-color: var(--border-soft); -} -.qtab-count { - font-family: var(--font-mono); - font-size: 11px; - color: var(--ink-3); - background: var(--paper); - border: 1px solid var(--border-soft); - border-radius: 5px; - padding: 0 5px; - font-feature-settings: "tnum" 1; - font-weight: 600; -} -.qtab.active .qtab-count { - background: #fff; - color: var(--ink); - border-color: var(--border); -} -.qtab-hot { - font-size: 10.5px; - color: var(--bloom-700); - font-weight: 700; - background: var(--bloom-50); - padding: 1px 6px; - border-radius: 4px; - border: 1px solid color-mix(in oklab, var(--bloom) 20%, transparent); -} - .queue-list { display: flex; flex-direction: column; } .qrow { display: grid; @@ -1027,6 +313,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } cursor: pointer; transition: background 100ms var(--ease-out); align-items: center; + position: relative; } .qrow:last-child { border-bottom: none; } .qrow:hover { background: var(--paper-2); } @@ -1034,17 +321,14 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } .qrow.selected { background: linear-gradient(90deg, color-mix(in oklab, var(--bloom) 8%, transparent) 0%, transparent 100%); } -.qrow.selected::before { +.qrow.selected::before, +.mail-row.selected::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2.5px; background: var(--bloom); } -.qrow { - position: relative; -} - .qrow .leading { width: 32px; height: 32px; display: flex; @@ -1061,10 +345,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } border-radius: 8px; padding: 3px; } -.qrow .leading.has-pin img { - width: 100%; height: 100%; - object-fit: contain; -} .qrow .leading.has-thumb { position: relative; background: var(--paper-2); @@ -1079,11 +359,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } height: 3px; background: var(--cat, transparent); } -.qrow .leading.has-thumb img { - width: 100%; height: 100%; - object-fit: cover; - display: block; -} .qrow .body { min-width: 0; } .qrow .body .top { @@ -1167,7 +442,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } .qrow:hover .row-arrow { opacity: 1; transform: translateX(2px); color: var(--ink-3); } .qrow.selected .row-arrow { opacity: 1; color: var(--bloom); } -/* Pills */ .pill { display: inline-flex; align-items: center; @@ -1183,8 +457,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } } .pill.tight { padding: 0px 6px; font-size: 10px; } .pill .dot { width: 4.5px; height: 4.5px; border-radius: 50%; background: currentColor; } -.pill.priority-high { background: var(--bloom-50); color: var(--bloom-700); border-color: color-mix(in oklab, var(--bloom) 18%, transparent); } -.pill.priority-med { background: var(--sun-50); color: var(--sun-700); border-color: color-mix(in oklab, var(--sun) 28%, transparent); } .pill.priority-low { background: var(--paper-2); color: var(--ink-2); border-color: var(--border-soft); } .pill.status-new { background: var(--sky-50); color: var(--sky-700); border-color: color-mix(in oklab, var(--sky) 20%, transparent); } .pill.status-progress { background: var(--lilac-50); color: var(--lilac-600); border-color: color-mix(in oklab, var(--lilac) 18%, transparent); } @@ -1201,26 +473,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } letter-spacing: 0.03em; text-transform: uppercase; } -.pill.kbd { - font-family: var(--font-mono); - background: var(--paper-2); - border-color: var(--border-soft); - color: var(--ink-3); - font-weight: 600; -} -.led { - display: inline-block; - width: 7px; height: 7px; - border-radius: 50%; -} -.led.ok { background: var(--moss); } -.led.warn { background: var(--sun-600); } -.led.bad { background: var(--bloom); } - -/* --------------------------------------------------------- - Buttons - --------------------------------------------------------- */ .btn { display: inline-flex; align-items: center; @@ -1234,7 +487,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } line-height: 1; border-radius: 8px; border: 1px solid var(--border-soft); - background: #fff; + background: var(--card); color: var(--ink); transition: background 120ms var(--ease-out), border-color 120ms var(--ease-out), transform 120ms var(--ease-out); white-space: nowrap; @@ -1247,7 +500,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } .btn:active { transform: scale(0.97); } .btn.primary { background: var(--bloom); - color: #fff; + color: var(--fg-on-color); border-color: transparent; box-shadow: 0 1px 0 var(--bloom-600), var(--sheen-top); font-weight: 700; @@ -1255,14 +508,14 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } .btn.primary:hover { background: var(--bloom-600); } .btn.success { background: var(--moss); - color: #fff; + color: var(--fg-on-color); border-color: transparent; box-shadow: 0 1px 0 var(--moss-600), var(--sheen-top); font-weight: 700; } .btn.success:hover { background: var(--moss-600); } .btn.danger { - background: #fff; + background: var(--card); color: var(--bloom-700); border-color: color-mix(in oklab, var(--bloom) 25%, transparent); } @@ -1293,9 +546,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } color: var(--ink-3); } -/* --------------------------------------------------------- - Slide-over task panel - --------------------------------------------------------- */ .panel-overlay { position: fixed; inset: 0; @@ -1329,7 +579,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } .panel-head { padding: 12px 18px 14px; border-bottom: 1px solid var(--border-soft); - background: #fff; + background: var(--card); display: flex; align-items: center; gap: 12px; @@ -1357,18 +607,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } text-overflow: ellipsis; } .panel-head .spacer { flex: 1; } -.panel-head .nav-arr { - width: 28px; height: 28px; - display: inline-flex; - align-items: center; - justify-content: center; - border-radius: 7px; - border: 1px solid var(--border-soft); - background: #fff; - color: var(--ink-2); - transition: background 120ms var(--ease-out); -} -.panel-head .nav-arr:hover { background: var(--paper-2); } .panel-head .closebtn { width: 32px; height: 32px; border-radius: 7px; @@ -1410,18 +648,16 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } .panel-foot { border-top: 1px solid var(--border-soft); - background: #fff; + background: var(--card); padding: 12px 20px; display: flex; align-items: center; gap: 8px; } -.panel-foot .left { display: flex; align-items: center; gap: 8px; } .panel-foot .spacer { flex: 1; } -/* Sub sections inside panel */ .sub { - background: #fff; + background: var(--card); border: 1px solid var(--border-soft); border-radius: 10px; overflow: hidden; @@ -1445,52 +681,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } } .sub > .sub-body { padding: 14px; } -/* Report preview */ -.report-preview { - display: flex; - gap: 12px; - padding: 10px; - background: var(--paper-2); - border-radius: 10px; - border: 1px solid var(--border-soft); -} -.report-preview .photo { - width: 88px; height: 88px; - border-radius: 8px; - background-image: - linear-gradient(135deg, var(--ink-4) 0%, var(--ink-5) 60%, var(--moss-100) 100%); - background-size: cover; - flex-shrink: 0; - position: relative; - border: 1px solid var(--border-soft); -} -.report-preview .photo .pin-on-photo { - position: absolute; - bottom: 4px; right: 4px; - width: 18px; height: 22px; - border-radius: 50% 50% 50% 4px; - transform: rotate(-45deg); - background: var(--bloom); - box-shadow: var(--shadow-2); -} -.report-preview .info { flex: 1; min-width: 0; } -.report-preview .info .desc { - font-size: 13px; - color: var(--ink); - line-height: 1.4; - text-wrap: pretty; -} -.report-preview .info .row { - font-size: 11px; - color: var(--ink-3); - margin-top: 6px; - display: flex; - gap: 6px; - flex-wrap: wrap; -} -.report-preview .info .row .strong { color: var(--ink-2); font-weight: 700; } - -/* Mini map in panel */ .mini-map { height: 140px; background: @@ -1508,38 +698,14 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } font-family: var(--font-display); font-variation-settings: "opsz" 38, "wdth" 85; font-weight: 700; font-size: 22px; letter-spacing: -0.02em; line-height: 1; - font-feature-settings: "tnum" 1; color: var(--ink); -} -.juris-stat-sub { font-size: 11px; color: var(--ink-3); margin-top: 2px; } -.mini-map .juris-shape { - position: absolute; - inset: 16px; - border: 2px dashed color-mix(in oklab, var(--bloom) 55%, transparent); - background: color-mix(in oklab, var(--bloom) 5%, transparent); - border-radius: 22px 30px 24px 32px / 28px 22px 30px 26px; - transform: rotate(-3deg); -} -.mini-map .juris-pin { - position: absolute; - top: 50%; left: 50%; - width: 22px; height: 28px; - border-radius: 50% 50% 50% 4px; - transform: translate(-50%, -90%) rotate(-45deg); - background: var(--bloom); - box-shadow: var(--shadow-2); -} -.mini-map .juris-pin::after { - content: ''; - position: absolute; - inset: 7px; - background: #fff; - border-radius: 50%; + font-feature-settings: "tnum" 1; color: var(--ink); } +.juris-stat-sub { font-size: 11px; color: var(--ink-3); margin-top: 2px; } .mini-map .juris-label { position: absolute; top: 50%; left: 50%; transform: translate(-50%, calc(-50% + 22px)); - background: #fff; + background: var(--card); padding: 3px 10px; border-radius: 999px; border: 1px solid var(--border-soft); @@ -1549,111 +715,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } box-shadow: var(--shadow-1); white-space: nowrap; } -.mini-map .scribble { - position: absolute; - inset: 0; - background-image: url('/ds/topo-pattern.svg'); - background-size: 200px; - opacity: 0.13; - pointer-events: none; -} - -/* Browser pane mock */ -.browser-pane { - border: 1px solid var(--border); - border-radius: 10px; - overflow: hidden; - background: #fff; -} -.browser-tabs { - display: flex; - gap: 4px; - padding: 6px 10px 0; - background: var(--paper-2); - border-bottom: 1px solid var(--border-soft); - overflow: hidden; -} -.browser-tab { - font-size: 11px; - padding: 4px 10px; - background: var(--paper); - border: 1px solid var(--border-soft); - border-bottom: none; - border-radius: 6px 6px 0 0; - color: var(--ink-3); - font-weight: 600; - white-space: nowrap; - max-width: min(200px, 100%); - min-width: 0; - overflow: hidden; - text-overflow: ellipsis; -} -.browser-tab.active { background: #fff; color: var(--ink); } -.browser-bar { - background: var(--paper-2); - padding: 7px 10px; - display: flex; - align-items: center; - gap: 8px; - border-bottom: 1px solid var(--border-soft); -} -.browser-bar .tld { - display: inline-flex; - gap: 5px; - align-items: center; -} -.browser-bar .tld span { - width: 9px; height: 9px; - border-radius: 50%; - background: var(--ink-4); -} -.browser-bar .tld span.r { background: #ff5f57; } -.browser-bar .tld span.y { background: #febc2e; } -.browser-bar .tld span.g { background: #28c840; } -.browser-bar .url { - flex: 1; - background: #fff; - border-radius: 5px; - padding: 4px 9px; - font-family: var(--font-mono); - font-size: 11px; - color: var(--ink-2); - border: 1px solid var(--border-soft); - display: flex; - align-items: center; - gap: 6px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} -.browser-content { - height: 180px; - padding: 14px; - background: #fff; - position: relative; - overflow: hidden; -} -.browser-content .g-result { margin-bottom: 12px; } -.browser-content .g-result .crumb { - font-size: 10.5px; - color: var(--ink-3); - font-family: var(--font-mono); -} -.browser-content .g-result .ttl { - font-size: 13px; - color: var(--sky-700); - font-weight: 600; - margin: 2px 0; - text-decoration: underline; - text-decoration-color: color-mix(in oklab, var(--sky) 30%, transparent); -} -.browser-content .g-result .snip { - font-size: 11px; - color: var(--ink-2); - line-height: 1.4; -} -/* Fields */ .field { display: flex; flex-direction: column; @@ -1662,6 +724,9 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } } .field:last-child { margin-bottom: 0; } .field .lbl { + display: flex; + align-items: center; + gap: 4px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; @@ -1677,7 +742,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } } .field input, .field textarea, .field select { border: 1px solid var(--border); - background: #fff; + background: var(--card); border-radius: 7px; padding: 8px 11px; font-family: var(--font-body); @@ -1692,9 +757,17 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } box-shadow: var(--ring); } .field textarea { resize: vertical; min-height: 56px; } -.field .hint { font-size: 11px; color: var(--ink-3); margin-top: 1px; } +.field .hint { + display: flex; + align-items: flex-start; + gap: 4px; + font-size: 11px; + line-height: 1.45; + color: var(--ink-3); + margin-top: 1px; + overflow-wrap: anywhere; +} -/* -- Per-report-type routing contacts --------------------- */ .ccat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr)); @@ -1713,7 +786,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } } .ccat-cell-head { display: flex; align-items: center; gap: 8px; } .ccat-pin { width: 22px; height: 22px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; } -.ccat-pin img { width: 100%; height: 100%; object-fit: contain; } .ccat-label { font-weight: 700; font-size: 12.5px; color: var(--ink); letter-spacing: -0.005em; } .sub-caption { font-size: 11px; color: var(--ink-3); line-height: 1.4; margin-top: -2px; overflow-wrap: anywhere; } .ccat-count { @@ -1723,7 +795,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } font-size: 10.5px; font-weight: 600; color: var(--ink-2); - background: #fff; + background: var(--card); border: 1px solid var(--border-soft); border-radius: 999px; padding: 1px 7px; @@ -1744,7 +816,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } align-items: center; gap: 7px; border: 1px solid var(--border); - background: #fff; + background: var(--card); border-radius: 8px; padding: 0 9px; color: var(--ink-4); @@ -1762,101 +834,14 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } color: var(--ink); padding: 8px 0; } -.tag-input { - display: flex; - flex-wrap: wrap; - gap: 4px; - padding: 4px; - border: 1px solid var(--border); - background: #fff; - border-radius: 7px; - min-height: 36px; - align-items: center; -} -.tag-input .tag { - background: var(--moss-50); - color: var(--moss-700); - font-size: 11.5px; - padding: 3px 7px 3px 8px; - border-radius: 5px; - font-weight: 600; - border: 1px solid color-mix(in oklab, var(--moss) 18%, transparent); - display: inline-flex; - align-items: center; - gap: 4px; -} -.tag-input .tag .x { - color: var(--moss-700); - opacity: 0.6; - cursor: pointer; -} -.tag-input .tag .x:hover { opacity: 1; } -.tag-input input { - flex: 1; - min-width: 80px; - border: none; - background: transparent; - padding: 3px 6px; - font-size: 13px; - color: var(--ink); - outline: none; -} - -/* Similar nearby + notes */ -.similar-list { display: flex; flex-direction: column; gap: 2px; } -.similar-row { - display: flex; - align-items: center; - gap: 9px; - padding: 7px 8px; - border-radius: 6px; - font-size: 12.5px; - cursor: pointer; - transition: background 120ms var(--ease-out); -} -.similar-row:hover { background: var(--paper-2); } -.similar-row .city { font-weight: 700; color: var(--ink); } -.similar-row .state { - color: var(--ink-3); - font-family: var(--font-mono); - font-size: 10.5px; -} -.similar-row .reuse { - margin-left: auto; - font-size: 10.5px; - color: var(--moss-700); - background: var(--moss-50); - padding: 1px 7px; - border-radius: 999px; - font-weight: 700; - border: 1px solid color-mix(in oklab, var(--moss) 18%, transparent); -} - -.notes { display: flex; flex-direction: column; gap: 8px; } -.note { - font-size: 12.5px; - color: var(--ink-2); - background: var(--sun-50); - border-left: 2px solid var(--sun); - padding: 8px 11px; - border-radius: 0 6px 6px 0; - line-height: 1.4; -} -.note .meta { - font-size: 10.5px; - color: var(--ink-3); - font-family: var(--font-mono); - margin-top: 4px; -} -/* Toast */ .toast-wrap { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%) translateY(100px); background: var(--ink); - color: #fff; + color: var(--fg-on-color); padding: 10px 16px 10px 14px; border-radius: 999px; box-shadow: var(--shadow-4); @@ -1887,7 +872,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } display: inline-flex; align-items: center; justify-content: center; - color: #fff; + color: var(--fg-on-color); } .toast-wrap .undo { margin-left: 6px; @@ -1896,29 +881,9 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } cursor: pointer; } -/* Util */ -.mono { font-family: var(--font-mono); font-feature-settings: "tnum" 1; } +.mono { font-feature-settings: "tnum" 1; } .muted { color: var(--ink-3); } .row-flex { display: flex; align-items: center; gap: 8px; } -.row-flex.wrap { flex-wrap: wrap; } - -/* Tweaks panel */ -#tweaks-host { z-index: 100; } - -/* ========================================================= - Pages: toolbar, filters, search - ========================================================= */ -.statcell.clickable { - border: none; - border-right: 1px solid var(--border-soft); - background: transparent; - text-align: left; - font: inherit; - cursor: pointer; - transition: background 120ms var(--ease-out); -} -.statcell.clickable:last-child { border-right: none; } -.statcell.clickable:hover { background: var(--paper-2); } .toolbar { display: flex; @@ -1936,7 +901,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } padding: 0 13px; border-radius: 8px; border: 1px solid var(--border-soft); - background: #fff; + background: var(--card); font-size: 12.5px; font-weight: 600; color: var(--ink-2); @@ -1946,7 +911,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } .fchip:hover { background: var(--paper-2); border-color: var(--border); } .fchip.active { background: var(--ink); - color: #fff; + color: var(--fg-on-color); border-color: var(--ink); } .fchip-count { @@ -1959,7 +924,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } color: var(--ink-3); font-feature-settings: "tnum" 1; } -.fchip.active .fchip-count { background: rgba(255,255,255,0.18); color: #fff; } +.fchip.active .fchip-count { background: rgba(255,255,255,0.18); color: var(--fg-on-color); } .searchbox { display: flex; @@ -1967,7 +932,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } gap: 8px; height: 34px; padding: 0 11px; - background: #fff; + background: var(--card); border: 1px solid var(--border-soft); border-radius: 8px; color: var(--ink-3); @@ -2000,7 +965,7 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } .sortbox-label { font-weight: 600; letter-spacing: 0.02em; } .sortbox select { border: 1px solid var(--border-soft); - background: #fff; + background: var(--card); border-radius: 8px; height: 34px; padding: 0 10px; @@ -2012,7 +977,6 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } } .sortbox select:focus { border-color: var(--bloom); box-shadow: var(--ring); } -/* Empty state */ .empty-state { display: flex; flex-direction: column; @@ -2029,246 +993,83 @@ button:focus-visible { outline: none; box-shadow: var(--ring); } color: var(--moss-600); display: flex; align-items: center; - justify-content: center; - margin-bottom: 12px; -} -.empty-title { font-weight: 700; font-size: 15px; color: var(--ink); } -.empty-sub { font-size: 13px; color: var(--ink-3); margin-top: 4px; max-width: 36ch; } - -/* Master-detail layout */ -.master-detail { - display: grid; - grid-template-columns: minmax(0, 360px) minmax(0, 1fr); - gap: var(--gutter); - align-items: start; -} -.md-list { position: sticky; top: calc(var(--topbar-h) + var(--gutter)); max-height: calc(100vh - var(--topbar-h) - var(--gutter) * 2); } -.md-list .queue-list { overflow-y: auto; } -.md-detail-card { min-height: 480px; } -@media (max-width: 980px) { - .master-detail { grid-template-columns: 1fr; } - .md-list { position: static; max-height: none; } -} - -/* Generic table */ -.table { display: flex; flex-direction: column; } -/* Horizontal scroll container for grid "tables" on narrow viewports: the table keeps a sane - minimum width and the WRAPPER scrolls, so the page itself never scrolls sideways. */ -.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; min-width: 0; max-width: 100%; } -.table-scroll > .table { min-width: 100%; } -.table-scroll > .table:has(> .trow:not(.jt):not(.ct)) { min-width: 640px; } -.table-scroll > .table:has(> .trow.jt), .table-scroll > .table:has(> .trow.ct) { min-width: 300px; } -.trow { - display: grid; - grid-template-columns: 1.5fr 1.2fr 1.6fr 1.2fr 0.9fr 1fr; - gap: 12px; - align-items: center; - padding: 11px 14px; - border-bottom: 1px solid var(--border-soft); - font-size: 12.5px; - color: var(--ink-2); - cursor: pointer; - transition: background 100ms var(--ease-out); -} -.trow > * { min-width: 0; overflow-wrap: anywhere; } -.trow:last-child { border-bottom: none; } -.trow:not(.thead):hover { background: var(--paper-2); } -.trow.thead { - font-size: 10.5px; - font-weight: 700; - letter-spacing: 0.06em; - text-transform: uppercase; - color: var(--ink-3); - cursor: default; - background: var(--paper-2); -} -.trow.thead:hover { background: var(--paper-2); } -.trow .td-strong { font-weight: 700; color: var(--ink); } -.trow .td-route { font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } -.trow .td-bad { color: var(--bloom-700); font-weight: 700; } -.trow.jt { grid-template-columns: 2fr 0.6fr 0.8fr; } - -/* card padding helper */ -.card-pad { padding: 16px; } - -/* ========================================================= - Moderation detail - ========================================================= */ -.mod-detail { display: flex; flex-direction: column; height: 100%; } -.mod-detail-head { - display: flex; - align-items: flex-start; - justify-content: space-between; - gap: 12px; - padding: 16px 16px 12px; -} -.mod-detail-head h2 { - font-family: var(--font-display); - font-weight: 700; - font-size: 19px; - letter-spacing: -0.015em; - margin: 0; -} -.mod-detail-head .crumb { - font-size: 10.5px; - color: var(--ink-3); - letter-spacing: 0.06em; - text-transform: uppercase; - font-weight: 700; - margin-bottom: 4px; - white-space: nowrap; -} -.mod-auto { - display: flex; - align-items: center; - gap: 7px; - margin: 0 16px 14px; - padding: 8px 12px; - background: var(--sun-50); - border: 1px solid color-mix(in oklab, var(--sun) 26%, transparent); - border-radius: 8px; - font-size: 12px; - font-weight: 600; - color: var(--sun-700); -} -.mod-detail-grid { - display: grid; - grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); - gap: 14px; - padding: 0 16px; - flex: 1; -} -@media (max-width: 720px) { .mod-detail-grid { grid-template-columns: 1fr; } } -.mod-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; } - -.mod-media { display: flex; gap: 12px; flex-wrap: wrap; } -.mod-photo { - width: 120px; height: 120px; max-width: 100%; - border-radius: 10px; - background: - repeating-linear-gradient(45deg, color-mix(in oklab, var(--cat) 18%, var(--paper-2)) 0 10px, var(--paper-2) 10px 20px); - border: 1px solid var(--border-soft); - position: relative; - flex-shrink: 0; - overflow: hidden; -} -.mod-photo-pin { - position: absolute; - left: 50%; top: 50%; - transform: translate(-50%, -50%); - width: 38px; height: 38px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - filter: blur(0.5px); - opacity: 0.85; -} -.mod-photo-pin img { width: 22px; height: 22px; filter: brightness(0) invert(1); } -.mod-photo-flag { - position: absolute; - bottom: 6px; left: 6px; - display: inline-flex; - align-items: center; - gap: 4px; - background: rgba(26,23,20,0.7); - color: #fff; - font-size: 10px; - font-weight: 700; - padding: 2px 7px; - border-radius: 6px; - backdrop-filter: blur(4px); + justify-content: center; + margin-bottom: 12px; } -.mod-media-meta { flex: 1; min-width: 0; } -.mod-media-meta .desc { font-size: 13px; color: var(--ink); line-height: 1.45; text-wrap: pretty; } -.mod-media-meta .row { margin-top: 8px; font-size: 11.5px; color: var(--ink-3); } -.mod-textblock p { font-size: 13.5px; color: var(--ink); line-height: 1.5; margin: 0 0 8px; text-wrap: pretty; } +.empty-title { font-weight: 700; font-size: 15px; color: var(--ink); } +.empty-sub { font-size: 13px; color: var(--ink-3); margin-top: 4px; max-width: 36ch; } -.signal-grid { +.master-detail { display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 8px; + grid-template-columns: minmax(0, 360px) minmax(0, 1fr); + gap: var(--gutter); + align-items: start; } -.signal { - padding: 10px 12px; - border-radius: 9px; - background: var(--paper-2); - border: 1px solid var(--border-soft); +.md-list { position: sticky; top: calc(var(--topbar-h) + var(--gutter)); max-height: calc(100vh - var(--topbar-h) - var(--gutter) * 2); } +.md-list .queue-list { overflow-y: auto; } +.md-detail-card { min-height: 480px; } +@media (max-width: 980px) { + .master-detail { grid-template-columns: 1fr; } + .md-list { position: static; max-height: none; } } -.signal-val { - font-family: var(--font-mono); + +.table { display: flex; flex-direction: column; } +/* Horizontal scroll container for grid "tables" on narrow viewports: the table keeps a sane + minimum width and the WRAPPER scrolls, so the page itself never scrolls sideways. */ +.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; min-width: 0; max-width: 100%; } +.table-scroll > .table { min-width: 100%; } +.table-scroll > .table:has(> .trow:not(.jt):not(.ct)) { min-width: 640px; } +.table-scroll > .table:has(> .trow.jt), .table-scroll > .table:has(> .trow.ct) { min-width: 300px; } +.trow { + display: grid; + grid-template-columns: 1.5fr 1.2fr 1.6fr 1.2fr 0.9fr 1fr; + gap: 12px; + align-items: center; + padding: 11px 14px; + border-bottom: 1px solid var(--border-soft); + font-size: 12.5px; + color: var(--ink-2); + cursor: pointer; + transition: background 100ms var(--ease-out); +} +.trow > * { min-width: 0; overflow-wrap: anywhere; } +.trow:last-child { border-bottom: none; } +.trow:not(.thead):hover { background: var(--paper-2); } +.trow.thead { + font-size: 10.5px; font-weight: 700; - font-size: 16px; - letter-spacing: -0.01em; - color: var(--ink); - font-feature-settings: "tnum" 1; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--ink-3); + cursor: default; + background: var(--paper-2); } -.signal-label { font-size: 11px; color: var(--ink-3); margin-top: 2px; font-weight: 600; } -.signal.tone-bad { background: var(--bloom-50); border-color: color-mix(in oklab, var(--bloom) 18%, transparent); } -.signal.tone-bad .signal-val { color: var(--bloom-700); } -.signal.tone-warn { background: var(--sun-50); border-color: color-mix(in oklab, var(--sun) 26%, transparent); } -.signal.tone-warn .signal-val { color: var(--sun-700); } -.signal.tone-ok .signal-val { color: var(--moss-700); } +.trow.thead:hover { background: var(--paper-2); } +.trow .td-strong { font-weight: 700; color: var(--ink); } +.trow.jt { grid-template-columns: 2fr 0.6fr 0.8fr; } + +.card-pad { padding: 16px; } -/* User context block (in moderation + users) */ .user-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; } .user-head > div { flex: 1; min-width: 0; } .user-av { width: 36px; height: 36px; border-radius: 50%; - color: #fff; + color: var(--fg-on-color); display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px; flex-shrink: 0; - /* Per-seed brand color is set inline (matching the shared Avatar's solid fill, NOT a single hardcoded - gradient). When the user has a real photo this is an rendered at the same size, cover-cropped. */ overflow: hidden; } -/* The real-photo variant: same circle, the uploaded/provider avatar fills it (center-cover) so admin - shows the IDENTICAL photo as web/mobile. object-fit keeps the aspect ratio inside the round clip. */ img.user-av { object-fit: cover; background: var(--paper-2); } .user-av.lg { width: 48px; height: 48px; font-size: 16px; } .user-name { font-weight: 700; font-size: 14px; color: var(--ink); } .user-handle { font-size: 11.5px; color: var(--ink-3); } -.user-stats { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 8px; - margin-bottom: 12px; -} -.user-stats.wide { grid-template-columns: repeat(4, 1fr); } -.ustat { - text-align: center; - padding: 10px 4px; - background: var(--paper-2); - border: 1px solid var(--border-soft); - border-radius: 9px; -} -.ustat-n { - display: block; - font-family: var(--font-display); - font-variation-settings: "opsz" 24, "wdth" 90; - font-weight: 700; - font-size: 20px; - letter-spacing: -0.02em; - color: var(--ink); - font-feature-settings: "tnum" 1; -} -.ustat-n.bad { color: var(--bloom-700); } -.ustat-n.warn { color: var(--sun-700); } -.ustat-l { font-size: 10.5px; color: var(--ink-3); font-weight: 600; } .user-meta-rows { display: flex; flex-direction: column; gap: 1px; } -.user-meta-rows.boxed { - background: var(--paper-2); - border: 1px solid var(--border-soft); - border-radius: 9px; - padding: 4px 12px; - margin-bottom: 14px; -} .umr { display: grid; grid-template-columns: auto minmax(0, 1fr); @@ -2284,25 +1085,20 @@ img.user-av { object-fit: cover; background: var(--paper-2); } break them anywhere rather than pushing the panel sideways. */ .umr > span:last-child { text-align: right; min-width: 0; overflow-wrap: anywhere; } .umr > span:last-child a { overflow-wrap: anywhere; } -.user-meta-rows.boxed .umr:last-child { border-bottom: none; } .umr .strong { color: var(--ink); font-weight: 700; } .btn.full { width: 100%; justify-content: center; margin-top: 10px; } -.mod-actions, .user-actions { +.user-actions { display: flex; align-items: center; gap: 8px; padding: 14px 16px; border-top: 1px solid var(--border-soft); - margin-top: 14px; + margin-top: 0; flex-wrap: wrap; } -.user-actions { margin-top: 0; } -/* ========================================================= - Reports detail - ========================================================= */ -.rep-detail { display: flex; flex-direction: column; height: 100%; } +.rep-detail, .user-detail, .mail-reader { display: flex; flex-direction: column; height: 100%; } .rep-head { display: flex; align-items: center; @@ -2310,7 +1106,12 @@ img.user-av { object-fit: cover; background: var(--paper-2); } padding: 16px 16px 12px; } .rep-head-pin { width: 34px; height: 34px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; } -.rep-head-pin img { width: 100%; height: 100%; object-fit: contain; } +.map-active-card .mac-pin img, +.qrow .leading.has-pin img, +.ccat-pin img, +.rep-head-pin img, +.prow-pin img, +.peek-pin img { width: 100%; height: 100%; object-fit: contain; } .rep-head-text { flex: 1; min-width: 0; } .rep-head-text .crumb { font-size: 10.5px; color: var(--ink-3); letter-spacing: 0.05em; @@ -2323,30 +1124,6 @@ img.user-av { object-fit: cover; background: var(--paper-2); } line-height: 1.15; text-wrap: pretty; } -.rep-statusbar { - display: flex; - align-items: center; - gap: 12px; - padding: 10px 16px; - margin: 0 16px 4px; - background: var(--paper-2); - border: 1px solid var(--border-soft); - border-radius: 11px; - flex-wrap: wrap; -} -.rep-statusbar-label { font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-3); } -.rep-submitted { font-size: 11.5px; color: var(--ink-3); font-family: var(--font-mono); } - -.status-seg { display: inline-flex; gap: 4px; background: #fff; border: 1px solid var(--border-soft); border-radius: 9px; padding: 3px; } -.status-seg-btn { - display: inline-flex; align-items: center; gap: 6px; - font-size: 12px; font-weight: 700; color: var(--ink-3); - padding: 5px 11px; border-radius: 6px; white-space: nowrap; - transition: background 120ms var(--ease-out), color 120ms var(--ease-out); -} -.status-seg-btn:hover { color: var(--ink); } -.status-seg-btn.on { background: var(--hue-50); color: var(--hue-700); } - .rep-grid { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); @@ -2399,7 +1176,7 @@ img.user-av { object-fit: cover; background: var(--paper-2); } .rep-photo-tag { position: absolute; bottom: 6px; left: 6px; display: inline-flex; align-items: center; gap: 4px; - background: rgba(26,23,20,0.72); color: #fff; + background: rgba(26,23,20,0.72); color: var(--fg-on-color); font-size: 9.5px; font-weight: 700; padding: 2px 7px; border-radius: 6px; } .rep-minimap { @@ -2408,7 +1185,6 @@ img.user-av { object-fit: cover; background: var(--paper-2); } border: 1px solid var(--border-soft); } -/* Timeline */ .rep-timeline { display: flex; flex-direction: column; } .rep-tl-row { display: flex; gap: 10px; padding: 7px 0; position: relative; } .rep-tl-row:not(:last-child)::before { @@ -2421,7 +1197,7 @@ img.user-av { object-fit: cover; background: var(--paper-2); } background: var(--paper-2); color: var(--ink-3); border: 1px solid var(--border-soft); position: relative; z-index: 1; } -.rep-tl-row.kind-confirm .rep-tl-ico { background: var(--moss-50); color: var(--moss-700); border-color: color-mix(in oklab, var(--moss) 20%, transparent); } +.rep-tl-row.kind-confirm .rep-tl-ico, .rep-tl-row.kind-done .rep-tl-ico { background: var(--moss-50); color: var(--moss-700); border-color: color-mix(in oklab, var(--moss) 20%, transparent); } .rep-tl-row.kind-warn .rep-tl-ico { background: var(--sun-50); color: var(--sun-700); border-color: color-mix(in oklab, var(--sun) 26%, transparent); } .rep-tl-row.kind-followup .rep-tl-ico { background: var(--sky-50); color: var(--sky-700); border-color: color-mix(in oklab, var(--sky) 20%, transparent); } @@ -2431,7 +1207,6 @@ img.user-av { object-fit: cover; background: var(--paper-2); } .rep-tl-text b { color: var(--ink); font-weight: 700; } .rep-tl-when { font-size: 10.5px; color: var(--ink-4); font-family: var(--font-mono); margin-top: 1px; } -/* Routed city block */ .rep-city { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; } .rep-city-ico { width: 34px; height: 34px; border-radius: 9px; flex-shrink: 0; @@ -2449,18 +1224,7 @@ img.user-av { object-fit: cover; background: var(--paper-2); } .rep-city-contact .mono { font-size: 11.5px; } .rep-city-contact.warn { background: var(--sun-50); border-color: color-mix(in oklab, var(--sun) 26%, transparent); color: var(--sun-700); font-weight: 600; } -/* Follow-up composer */ .rep-to { display: flex; gap: 6px; margin-bottom: 8px; } -.rep-to-btn { - flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; - font-size: 12px; font-weight: 700; color: var(--ink-3); - padding: 7px 10px; border-radius: 8px; - background: var(--paper-2); border: 1px solid var(--border-soft); - transition: background 120ms var(--ease-out), color 120ms var(--ease-out), border-color 120ms var(--ease-out); -} -.rep-to-btn:hover:not(:disabled) { color: var(--ink); } -.rep-to-btn.on { background: #fff; color: var(--sky-700); border-color: color-mix(in oklab, var(--sky) 32%, transparent); box-shadow: var(--shadow-1); } -.rep-to-btn:disabled { opacity: 0.45; cursor: not-allowed; } .rep-followup { width: 100%; resize: vertical; min-height: 64px; margin-bottom: 8px; border: 1px solid var(--border); border-radius: 9px; padding: 9px 11px; @@ -2476,16 +1240,15 @@ img.user-av { object-fit: cover; background: var(--paper-2); } } .rep-actions-label { font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-3); margin-right: 2px; } -/* -- Events ----------------------------------------------- */ .evt-row-ico { width: 30px; height: 30px; border-radius: 9px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; - background: var(--sun-50, #FFF6DC); color: var(--sun-700); + background: var(--sun-50); color: var(--sun-700); } .evt-head-ico { width: 38px; height: 38px; border-radius: 10px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; - background: var(--sun-50, #FFF6DC); color: var(--sun-700); + background: var(--sun-50); color: var(--sun-700); } .evt-turnout { display: flex; flex-direction: column; gap: 8px; } .evt-turnout-top { display: flex; align-items: baseline; justify-content: space-between; } @@ -2515,7 +1278,6 @@ img.user-av { object-fit: cover; background: var(--paper-2); } .evt-msg-text { grid-column: 1 / -1; font-size: 12.5px; color: var(--ink); line-height: 1.4; } .evt-post-hint { font-size: 11px; color: var(--ink-3); margin-top: 6px; } -/* -- Report discussion (public comment thread; distinct from the Activity timeline) -- */ .dsc-list { display: flex; flex-direction: column; gap: 10px; } .dsc-msg { display: flex; gap: 10px; @@ -2526,7 +1288,7 @@ img.user-av { object-fit: cover; background: var(--paper-2); } .dsc-msg-av { width: 28px; height: 28px; border-radius: 8px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; - font-size: 10.5px; font-weight: 700; color: #fff; + font-size: 10.5px; font-weight: 700; color: var(--fg-on-color); background: linear-gradient(135deg, var(--sky), var(--moss)); } .dsc-msg.removed .dsc-msg-av { background: var(--paper-2); color: var(--ink-4); border: 1px solid var(--border-soft); } @@ -2546,6 +1308,7 @@ img.user-av { object-fit: cover; background: var(--paper-2); } display: flex; align-items: center; justify-content: center; background: var(--paper); border: 1px solid var(--border-soft); color: var(--ink-4); } +.qrow .leading.has-thumb img, .dsc-msg-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; } .dsc-msg-foot { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; } .dsc-msg-reactions { display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; } @@ -2555,20 +1318,15 @@ img.user-av { object-fit: cover; background: var(--paper-2); } background: var(--paper); border: 1px solid var(--border-soft); } .dsc-reaction.mine { background: var(--bloom-50); color: var(--bloom-700); border-color: color-mix(in oklab, var(--bloom) 20%, transparent); } -.dsc-msg-replies { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--ink-3); font-weight: 600; } -.dsc-msg-replies svg { color: var(--ink-4); } -/* Operator composer under the report chat (same treatment as the Mail reply composer). */ .dsc-composer { border-top: 1px solid var(--border-soft); padding: 12px 14px 14px; } .dsc-composer-foot { display: flex; align-items: center; gap: 8px; } .dsc-composer-foot .hint { font-size: 11px; color: var(--ink-3); min-width: 0; } .dsc-composer-foot .spacer { flex: 1; min-width: 4px; } -/* Linked reports/events galleries (event<->report linking). A vertical list of clickable cards: a - thumb/glyph, a title, a status/kind sub-row, and an address/organizer line. Used on both the event - detail ("Linked reports") and the report detail ("Linked events"). */ .evt-linked-list { display: flex; flex-direction: column; gap: 8px; } -.evt-linked-card { +.evt-linked-card, +.evt-pick-row { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 8px 10px; border-radius: 10px; cursor: pointer; background: var(--paper-2); border: 1px solid var(--border-soft); @@ -2580,17 +1338,16 @@ img.user-av { object-fit: cover; background: var(--paper-2); } display: flex; align-items: center; justify-content: center; background: var(--paper); border: 1px solid var(--border-soft); color: var(--ink-3); } -.evt-linked-thumb.hue-sun { background: var(--sun-50, #FFF6DC); color: var(--sun-700); border-color: transparent; } +.evt-linked-thumb.hue-sun { background: var(--sun-50); color: var(--sun-700); border-color: transparent; } .evt-linked-thumb img { width: 100%; height: 100%; object-fit: cover; } -.evt-linked-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; } -.evt-linked-title { font-size: 13px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } -.evt-linked-sub { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ink-3); flex-wrap: wrap; } +.evt-linked-body, .evt-pick-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; } +.evt-linked-title, .evt-pick-title { font-size: 13px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.evt-linked-sub, .evt-pick-sub { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ink-3); flex-wrap: wrap; } .evt-linked-sub .sep { color: var(--ink-4); } .evt-linked-cat { font-weight: 600; } .evt-linked-addr { font-size: 11px; color: var(--ink-4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } -/* A linked-report row: the deep-link card plus a trailing operator unlink control (a card is a -