Spaces:
Sleeping
Sleeping
Download static/css/dda.css from coderuday21/satdetect-dev: direct link, hf CLI and curl.
- Browser
- Download file 75.3 kB
-
https://huggingface.co/spaces/coderuday21/satdetect-dev/resolve/c682b538bd223eaf5286645a12eb43003a6f536b/static/css/dda.css
- Command line
-
hf download hf://spaces/coderuday21/satdetect-dev@c682b538bd223eaf5286645a12eb43003a6f536b/static/css/dda.css
-
curl -L -o dda.css https://huggingface.co/spaces/coderuday21/satdetect-dev/resolve/c682b538bd223eaf5286645a12eb43003a6f536b/static/css/dda.css
75.3 kB
| /* Vedangsoft dev UI — extends style.css */ | |
| @import url('https://fonts.googleapis.com/css2?family=Archivo:wght@400;600;800&display=swap'); | |
| /* Modernist design tokens (from the Claude Design redesign) — shared by | |
| every screen that opts into the new look via its own scoped block below. | |
| Global/additive: these names don't collide with anything style.css | |
| already defines, so declaring them at :root can't affect pages that | |
| don't reference them. */ | |
| :root { | |
| --dm-bg: #f3f2f2; | |
| --dm-surface: #ffffff; | |
| --dm-line: rgba(32, 30, 29, 0.14); | |
| --dm-ink: #201e1d; | |
| --dm-ink-muted: #7d7979; | |
| --dm-ink-dim: #9b9797; | |
| --dm-accent: #ec3013; | |
| --dm-accent-hover: #dd2b0f; | |
| --dm-accent-100: #fff2ef; | |
| --dm-font: 'Archivo', system-ui, sans-serif; | |
| } | |
| .dda-app { | |
| max-width: 1600px; | |
| margin: 0 auto; | |
| display: flex; | |
| align-items: flex-start; | |
| min-height: 100vh; | |
| } | |
| /* --- Left sidebar navigation --- */ | |
| .dda-sidebar-nav { | |
| position: sticky; | |
| top: 0; | |
| flex: 0 0 252px; | |
| width: 252px; | |
| height: 100vh; | |
| overflow-y: auto; | |
| overflow-x: hidden; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1.75rem; | |
| padding: 1.5rem 1.15rem; | |
| border-right: 1px solid var(--border); | |
| background: var(--bg-surface); | |
| transition: flex-basis var(--transition), width var(--transition); | |
| } | |
| .dda-sidebar-brand { display: flex; align-items: center; gap: 0.65rem; padding: 0 0.15rem; } | |
| .dda-sidebar-toggle { | |
| margin-left: auto; | |
| flex-shrink: 0; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 28px; | |
| height: 28px; | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| background: transparent; | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| } | |
| .dda-sidebar-toggle:hover { background: var(--bg-hover); color: var(--text); } | |
| /* Collapsed state: icon-only rail, like the LMS reference sidebar. */ | |
| .dda-sidebar-nav.collapsed { flex-basis: 72px; width: 72px; padding-left: 0.6rem; padding-right: 0.6rem; } | |
| .dda-sidebar-nav.collapsed .dda-sidebar-brand { justify-content: center; } | |
| .dda-sidebar-nav.collapsed .dda-sidebar-brand-text { display: none; } | |
| .dda-sidebar-nav.collapsed .dda-sidebar-toggle { margin-left: 0; } | |
| .dda-sidebar-nav.collapsed .dda-tab { justify-content: center; padding: 0.65rem; } | |
| .dda-sidebar-nav.collapsed .dda-tab span, | |
| .dda-sidebar-nav.collapsed .dda-sidebar-chevron, | |
| .dda-sidebar-nav.collapsed .dda-notify-btn span, | |
| .dda-sidebar-nav.collapsed .dda-notify-badge, | |
| .dda-sidebar-nav.collapsed .dda-user-wrap #dda-user-email { display: none; } | |
| .dda-sidebar-nav.collapsed .dda-sidebar-submenu { display: none; } | |
| .dda-sidebar-nav.collapsed .dda-notify-wrap, | |
| .dda-sidebar-nav.collapsed .dda-user-wrap { justify-content: center; } | |
| .dda-sidebar-brand > svg { flex-shrink: 0; color: var(--grad-start); } | |
| .dda-sidebar-brand-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; } | |
| .dda-sidebar-brand-name { | |
| font-weight: 700; | |
| font-size: 1.02rem; | |
| background: var(--gradient); | |
| -webkit-background-clip: text; | |
| background-clip: text; | |
| color: transparent; | |
| } | |
| .dda-sidebar-brand-sub { | |
| font-size: 0.72rem; | |
| color: var(--text-dim); | |
| display: flex; | |
| align-items: center; | |
| gap: 0.4rem; | |
| } | |
| .dda-tabs { display: flex; flex-direction: column; gap: 0.25rem; } | |
| .dda-tab { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.7rem; | |
| padding: 0.65rem 0.8rem; | |
| border: 1px solid transparent; | |
| border-radius: var(--radius-sm); | |
| background: transparent; | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| font-size: 0.9rem; | |
| text-decoration: none; | |
| transition: all var(--transition); | |
| } | |
| .dda-tab svg { flex-shrink: 0; opacity: 0.85; } | |
| .dda-tab:hover { background: var(--bg-hover); color: var(--text); } | |
| .dda-tab.active { | |
| background: linear-gradient(135deg, rgba(46,51,197,0.10), rgba(207,32,64,0.07)); | |
| color: var(--grad-start); | |
| font-weight: 600; | |
| } | |
| .dda-tab.active svg { opacity: 1; } | |
| /* Collapsible sidebar group (e.g. "Configuration" > Roles & Users / App | |
| Modules / Menu Management) — native <details>/<summary>, no JS needed. */ | |
| .dda-sidebar-group { border: none; } | |
| .dda-sidebar-group > summary.dda-tab-group { | |
| list-style: none; | |
| justify-content: flex-start; | |
| } | |
| .dda-sidebar-group > summary.dda-tab-group::-webkit-details-marker { display: none; } | |
| .dda-sidebar-group > summary.dda-tab-group::marker { content: ""; } | |
| .dda-sidebar-chevron { margin-left: auto; flex-shrink: 0; opacity: 0.6; transition: transform var(--transition); } | |
| .dda-sidebar-group[open] > summary .dda-sidebar-chevron { transform: rotate(90deg); } | |
| .dda-sidebar-submenu { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.2rem; | |
| margin: 0.2rem 0 0.15rem 0.95rem; | |
| padding-left: 0.85rem; | |
| border-left: 1px solid var(--border); | |
| } | |
| .dda-subtab { padding: 0.5rem 0.7rem; font-size: 0.86rem; } | |
| .dda-sidebar-footer { | |
| margin-top: auto; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.6rem; | |
| padding-top: 1rem; | |
| border-top: 1px solid var(--border); | |
| } | |
| .dda-user-wrap { display: flex; align-items: center; gap: 0.55rem; font-size: 0.82rem; } | |
| .dda-user-avatar { | |
| flex-shrink: 0; | |
| width: 26px; | |
| height: 26px; | |
| border-radius: 50%; | |
| background: var(--gradient); | |
| color: #fff; | |
| font-size: 0.72rem; | |
| font-weight: 700; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .dda-user-wrap #dda-user-email { | |
| flex: 1 1 auto; | |
| min-width: 0; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| } | |
| /* User menu — click the avatar/email row to reveal My Profile / Sign out. | |
| Native <details>/<summary>, same zero-JS pattern as the sidebar's | |
| "Configuration" group. */ | |
| .dda-user-menu { border: none; } | |
| .dda-user-menu > summary.dda-user-wrap { list-style: none; cursor: pointer; } | |
| .dda-user-menu > summary.dda-user-wrap::-webkit-details-marker { display: none; } | |
| .dda-user-menu > summary.dda-user-wrap::marker { content: ""; } | |
| .dda-user-menu-panel { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.15rem; | |
| margin-top: 0.5rem; | |
| padding-top: 0.5rem; | |
| border-top: 1px solid var(--border); | |
| } | |
| .dda-user-menu-link { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.55rem; | |
| padding: 0.5rem 0.6rem; | |
| border: none; | |
| border-radius: var(--radius-sm); | |
| background: transparent; | |
| color: var(--text-muted); | |
| font-size: 0.85rem; | |
| text-decoration: none; | |
| cursor: pointer; | |
| width: 100%; | |
| text-align: left; | |
| } | |
| .dda-user-menu-link:hover { background: var(--bg-hover); color: var(--text); } | |
| .dda-user-menu-link.active { color: var(--grad-start); font-weight: 600; } | |
| .dda-user-menu-danger { color: var(--danger); } | |
| .dda-user-menu-danger:hover { background: rgba(207, 32, 64, 0.08); color: var(--danger); } | |
| /* Collapsed rail: the panel can't render inline at 72px, so it escapes as a | |
| fixed-position flyout instead — same reasoning as the notification panel | |
| (overflow-x:hidden on the sidebar would otherwise clip it). */ | |
| .dda-sidebar-nav.collapsed .dda-user-menu-panel { | |
| position: fixed; | |
| left: 84px; | |
| bottom: 1.25rem; | |
| width: 190px; | |
| margin-top: 0; | |
| padding: 0.5rem; | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| background: var(--bg-surface); | |
| box-shadow: 0 12px 28px rgba(0, 0, 0, 0.18); | |
| z-index: 30; | |
| } | |
| /* Main content column, to the right of the sidebar */ | |
| .dda-main-col { flex: 1 1 auto; min-width: 0; padding: 1.75rem 2rem 3rem; } | |
| .dda-hero { margin-bottom: 1.5rem; } | |
| .dda-hero h1 { margin-bottom: 0.35rem; } | |
| .dda-panel { display: none; } | |
| .dda-panel.active { display: block; } | |
| .dda-home-cards { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); | |
| gap: 1.1rem; | |
| margin-bottom: 1.5rem; | |
| } | |
| .dda-home-card { | |
| display: block; | |
| text-decoration: none; | |
| color: inherit; | |
| transition: border-color var(--transition), transform var(--transition), box-shadow var(--transition); | |
| } | |
| .dda-home-card:hover { | |
| border-color: var(--grad-start); | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 28px rgba(46, 51, 197, 0.1); | |
| } | |
| .dda-home-card-icon { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 40px; | |
| height: 40px; | |
| border-radius: var(--radius-sm); | |
| background: linear-gradient(135deg, rgba(46,51,197,0.12), rgba(207,32,64,0.08)); | |
| color: var(--grad-start); | |
| margin-bottom: 0.75rem; | |
| } | |
| .dda-home-card h3 { margin-bottom: 0.35rem; } | |
| /* Collapse the sidebar into a horizontal top bar on narrow viewports */ | |
| @media (max-width: 900px) { | |
| .dda-app { flex-direction: column; } | |
| .dda-sidebar-nav { | |
| position: static; | |
| width: 100%; | |
| height: auto; | |
| flex-direction: row; | |
| flex-wrap: wrap; | |
| align-items: center; | |
| border-right: none; | |
| border-bottom: 1px solid var(--border); | |
| gap: 1rem; | |
| } | |
| .dda-tabs { flex-direction: row; flex-wrap: wrap; } | |
| .dda-tab span { display: none; } | |
| .dda-tab { padding: 0.55rem; } | |
| .dda-sidebar-footer { | |
| margin-top: 0; | |
| margin-left: auto; | |
| flex-direction: row; | |
| align-items: center; | |
| border-top: none; | |
| padding-top: 0; | |
| } | |
| .dda-notify-wrap { width: auto; } | |
| .dda-notify-btn { width: auto; } | |
| .dda-notify-btn span { display: none; } | |
| .dda-user-wrap #dda-user-email { display: none; } | |
| .dda-main-col { padding: 1.25rem 1.25rem 2rem; } | |
| .dda-sidebar-toggle { display: none; } | |
| } | |
| .dda-layout { | |
| display: grid; | |
| grid-template-columns: minmax(220px, 280px) 1fr; | |
| gap: 1rem; | |
| align-items: start; | |
| } | |
| @media (max-width: 900px) { | |
| .dda-layout { grid-template-columns: 1fr; } | |
| } | |
| /* Library page: the upload form's fields flow into as few rows as fit | |
| (instead of a rigid 2-up grid that wraps to 3 rows) and the storage-path | |
| help text collapses behind <details> — together these keep the upload | |
| card short so the page reads as three compact sections, not four tall | |
| stacked cards. */ | |
| .dda-upload-row { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); } | |
| /* Detect page: manual-mode pairs + library grid split into their own cards | |
| (same pattern as the Library page) instead of nesting inside the main | |
| setup card — #dda-manual-compare is a plain wrapper, not a card, so its | |
| own spacing has to be set explicitly (the .card + .card rule only fires | |
| between adjacent .card elements). */ | |
| #dda-manual-compare { display: flex; flex-direction: column; gap: 1.25rem; margin: 1.25rem 0; } | |
| /* Reports page: paginated table (10/page — see reports.js) instead of | |
| letting the page grow with every past run. The search box + Refresh | |
| button live in their own no-wrap toolbar so they stay on one line next | |
| to the heading instead of the search stretching full-width and dropping | |
| Refresh to its own row. */ | |
| .dda-reports-toolbar { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.6rem; | |
| flex-shrink: 0; | |
| } | |
| .dda-reports-toolbar .dda-search { | |
| width: 220px; | |
| flex: none; | |
| margin-bottom: 0; | |
| } | |
| .dda-reports-toolbar .btn { flex-shrink: 0; } | |
| .dda-storage-info { margin-top: 0.85rem; border-top: 1px solid var(--border); padding-top: 0.6rem; } | |
| .dda-storage-info summary { | |
| cursor: pointer; | |
| font-size: 0.82rem; | |
| font-weight: 600; | |
| color: var(--text-muted); | |
| list-style: none; | |
| } | |
| .dda-storage-info summary::-webkit-details-marker { display: none; } | |
| .dda-storage-info summary::before { content: '▸ '; } | |
| .dda-storage-info[open] summary::before { content: '▾ '; } | |
| .dda-storage-info summary:hover { color: var(--grad-start); } | |
| .dda-storage-info .sub { margin-top: 0.5rem; } | |
| /* Fill down to the bottom of the viewport instead of stopping at a fixed | |
| 70vh and leaving a dead gap below the card when the tree list is short | |
| relative to the page's other content. `.dda-layout` uses align-items:start | |
| so grid items sit at their content height by default — align-self:stretch | |
| opts this one item back into matching the row's (taller, main-column) | |
| height, which max-height then caps at the viewport. */ | |
| .dda-sidebar { | |
| position: sticky; | |
| top: 1rem; | |
| align-self: stretch; | |
| max-height: calc(100vh - 2rem); | |
| overflow: auto; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .dda-sidebar #lib-tree, | |
| .dda-sidebar #compare-tree { flex: 1 1 auto; overflow-y: auto; } | |
| .dda-search { | |
| width: 100%; | |
| margin-bottom: 0.75rem; | |
| padding: 0.45rem 0.65rem; | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| background: var(--bg); | |
| color: var(--text); | |
| font-size: 0.88rem; | |
| } | |
| .dda-tree { font-size: 0.88rem; } | |
| .dda-tree-year { | |
| display: block; | |
| width: 100%; | |
| text-align: left; | |
| padding: 0.4rem 0.55rem; | |
| margin-bottom: 0.2rem; | |
| border: none; | |
| background: transparent; | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| border-radius: 6px; | |
| font-size: 0.9rem; | |
| font-weight: 500; | |
| } | |
| .dda-tree-year:hover, .dda-tree-year.active { | |
| background: var(--bg-hover); | |
| color: var(--grad-start); | |
| } | |
| .dda-sidebar-actions { display: flex; gap: 0.35rem; flex-wrap: wrap; } | |
| .dda-tree-all, .dda-tree-node-btn { | |
| display: block; | |
| width: 100%; | |
| text-align: left; | |
| padding: 0.35rem 0.5rem; | |
| margin-bottom: 0.2rem; | |
| border: none; | |
| background: transparent; | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| border-radius: 6px; | |
| font-size: 0.88rem; | |
| } | |
| .dda-tree-all:hover, .dda-tree-all.active, | |
| .dda-tree-node-btn:hover, .dda-tree-node-btn.active { | |
| background: var(--bg-hover); | |
| color: var(--grad-start); | |
| } | |
| .dda-tree-node-wrap { margin-bottom: 0.15rem; } | |
| .dda-tree-node-summary { list-style: none; cursor: pointer; } | |
| .dda-tree-node-summary .dda-tree-node-btn { display: inline; width: auto; } | |
| .dda-tree-children { padding-left: 0.65rem; border-left: 1px solid var(--border); margin-left: 0.35rem; } | |
| .dda-tree-toolbar { display: flex; gap: 0.5rem; margin: -0.35rem 0 0.6rem; } | |
| .dda-tree-toolbar-btn { | |
| border: none; | |
| background: transparent; | |
| color: var(--text-muted); | |
| font-size: 0.76rem; | |
| padding: 0; | |
| cursor: pointer; | |
| text-decoration: underline; | |
| text-underline-offset: 2px; | |
| } | |
| .dda-tree-toolbar-btn:hover { color: var(--grad-start); } | |
| .dda-tree-hit { background: rgba(255, 205, 60, 0.45); color: inherit; border-radius: 2px; } | |
| .dda-tree-leaf { padding-left: 0.75rem; } | |
| .dda-crumb { font-size: 0.78rem; line-height: 1.3; } | |
| .dda-manage-panel { max-width: 640px; width: 100%; } | |
| .dda-manage-section { margin-bottom: 1rem; } | |
| .dda-manage-section h4 { margin: 0 0 0.5rem; font-size: 0.9rem; } | |
| .dda-manage-section .location-row { flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.5rem; } | |
| .dda-folder-path { | |
| font-size: 0.78rem; | |
| margin-bottom: 0.6rem; | |
| word-break: break-all; | |
| } | |
| .dda-path-code { | |
| background: var(--bg); | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| padding: 0.6rem 0.75rem; | |
| font-size: 0.8rem; | |
| overflow-x: auto; | |
| margin: 0.5rem 0 0; | |
| } | |
| .dda-instructions .sub code { | |
| font-size: 0.85em; | |
| background: var(--bg); | |
| padding: 0.1rem 0.35rem; | |
| border-radius: 4px; | |
| } | |
| .card-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 0.5rem; | |
| flex-wrap: wrap; | |
| } | |
| .dda-tree-zone > button { | |
| width: 100%; | |
| text-align: left; | |
| padding: 0.35rem 0.5rem; | |
| border: none; | |
| background: transparent; | |
| color: var(--text); | |
| cursor: pointer; | |
| border-radius: 4px; | |
| font-weight: 600; | |
| } | |
| .dda-tree-zone > button:hover { background: var(--bg-hover); } | |
| .dda-tree-villages { padding-left: 0.75rem; display: none; } | |
| .dda-tree-zone.open .dda-tree-villages { display: block; } | |
| .dda-tree-village { | |
| display: block; | |
| width: 100%; | |
| text-align: left; | |
| padding: 0.3rem 0.5rem; | |
| border: none; | |
| background: transparent; | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| border-radius: 4px; | |
| font-size: 0.85rem; | |
| } | |
| .dda-tree-village:hover, .dda-tree-village.active { | |
| background: var(--bg-hover); | |
| color: var(--grad-start); | |
| } | |
| .dda-grid { | |
| display: grid; | |
| /* minmax(150px, 1fr) with auto-fill (not auto-fit): column tracks are | |
| shared across every row, so all rows stay evenly sized regardless of | |
| how many cards the last row has — auto-fit was the thing that caused | |
| uneven stretching, not minmax itself. This fills the row's full width | |
| instead of leaving a fixed-150px grid short of the container edge. */ | |
| grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); | |
| gap: 0.75rem; | |
| min-height: 80px; | |
| align-content: start; | |
| } | |
| .dda-card-img { | |
| position: relative; | |
| display: flex; | |
| flex-direction: column; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| overflow: hidden; | |
| background: var(--bg-elevated); | |
| cursor: pointer; | |
| transition: border-color var(--transition); | |
| } | |
| .dda-card-img[draggable="true"] { cursor: grab; } | |
| .dda-card-img:hover { border-color: var(--grad-start); } | |
| .dda-card-img img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; pointer-events: none; } | |
| .dda-card-delete-btn { | |
| position: absolute; | |
| top: 6px; | |
| right: 6px; | |
| z-index: 2; | |
| width: 26px; | |
| height: 26px; | |
| border: none; | |
| border-radius: 6px; | |
| background: rgba(0, 0, 0, 0.62); | |
| color: #fff; | |
| font-size: 1.1rem; | |
| line-height: 1; | |
| cursor: pointer; | |
| opacity: 0; | |
| transition: opacity var(--transition), background var(--transition); | |
| } | |
| .dda-card-img:hover .dda-card-delete-btn, | |
| .dda-card-delete-btn:focus { opacity: 1; } | |
| .dda-card-delete-btn:hover { background: var(--danger, #dc2626); } | |
| .dda-card-img .meta { | |
| padding: 0.4rem 0.5rem; | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| line-height: 1.3; | |
| /* Fixed height regardless of path length — the variable-length crumb | |
| text (folder path + filename) was the other source of uneven card | |
| heights, wrapping to 1-4 lines depending on the image: crumb, optional | |
| village/zone place, capture date/type/size/dims, uploaded date. */ | |
| height: 5.2em; | |
| overflow: hidden; | |
| } | |
| .dda-card-img .meta .dda-crumb { | |
| display: block; | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| .dda-card-img .meta .dda-card-uploaded { | |
| display: block; | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| .dda-compare-slots { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 1rem; | |
| margin: 1rem 0; | |
| } | |
| .dda-slot { | |
| border: 2px dashed var(--border); | |
| border-radius: 10px; | |
| padding: 1rem; | |
| min-height: 120px; | |
| text-align: center; | |
| } | |
| .dda-image-select { | |
| width: 100%; | |
| margin: 0.5rem 0; | |
| padding: 0.45rem 0.55rem; | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| background: var(--bg); | |
| color: var(--text); | |
| font-size: 0.88rem; | |
| } | |
| .dda-slot-preview-wrap { min-height: 48px; margin: 0.35rem 0; } | |
| .dda-slot .dda-slot-pick { margin-top: 0.35rem; } | |
| .dda-slot.filled { border-style: solid; border-color: var(--grad-start); } | |
| .dda-slot.drag-over { border-color: var(--grad-start); background: rgba(45,212,191,0.06); } | |
| .dda-slot-label { display: block; font-weight: 600; margin-bottom: 0.5rem; } | |
| .dda-compare-library { margin: 1rem 0; } | |
| .dda-compare-assign .btn { | |
| pointer-events: auto; | |
| position: relative; | |
| z-index: 2; | |
| } | |
| .dda-compare-grid { min-height: 120px; } | |
| .dda-compare-card { position: relative; } | |
| .dda-compare-card.selected-t1 { border-color: #2dd4bf; box-shadow: 0 0 0 2px rgba(45,212,191,0.35); } | |
| .dda-compare-card.selected-t2 { border-color: #60a5fa; box-shadow: 0 0 0 2px rgba(96,165,250,0.35); } | |
| .dda-compare-assign { | |
| display: flex; | |
| gap: 0.35rem; | |
| padding: 0.45rem 0.5rem 0.55rem; | |
| border-top: 1px solid var(--border); | |
| } | |
| .dda-compare-assign .btn { flex: 1; font-size: 0.75rem; padding: 0.3rem 0.4rem; } | |
| .dda-reports-table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| font-size: 0.85rem; | |
| margin-top: 0.5rem; | |
| } | |
| .dda-reports-table th, .dda-reports-table td { | |
| border: 1px solid var(--border); | |
| padding: 0.4rem 0.55rem; | |
| text-align: left; | |
| } | |
| .dda-status { font-size: 0.78rem; font-weight: 600; text-transform: capitalize; } | |
| .dda-status-completed { color: var(--success, #16a34a); } | |
| .dda-status-running, .dda-status-queued { color: #ca8a04; } | |
| .dda-status-failed { color: var(--danger, #dc2626); } | |
| .dda-slot-preview { | |
| width: 100%; | |
| max-height: 160px; | |
| object-fit: contain; | |
| border-radius: 6px; | |
| margin: 0.5rem 0; | |
| background: var(--bg); | |
| } | |
| .dda-slot-meta { font-size: 0.82rem; color: var(--text-muted); margin-bottom: 0.5rem; } | |
| .dda-detect-options { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 1rem; | |
| align-items: flex-end; | |
| margin-bottom: 1rem; | |
| } | |
| .dda-detect-options .form-group { margin: 0; min-width: 160px; } | |
| .dda-check { display: flex; align-items: center; gap: 0.35rem; font-size: 0.88rem; color: var(--text-muted); } | |
| .dda-sensitivity-field label { display: flex; align-items: baseline; gap: 0.35rem; } | |
| .dda-sensitivity-field em { font-style: normal; color: var(--text); font-variant-numeric: tabular-nums; } | |
| .dda-sensitivity-field input[type="range"] { width: 100%; min-width: 140px; } | |
| .dda-field-hint { font-size: 0.78rem; margin: 0.3rem 0 0; color: var(--accent-dim); font-weight: 500; } | |
| /* Min region area: a unified [−] [140 px] [+] stepper control — one bordered | |
| group instead of a plain number input, since the browser's own spinner | |
| arrows collide with our "px" suffix and can't be styled consistently. */ | |
| .dda-stepper-wrap { | |
| display: flex; | |
| align-items: stretch; | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| background: var(--bg-elevated); | |
| overflow: hidden; | |
| transition: border-color var(--transition), box-shadow var(--transition); | |
| } | |
| .dda-stepper-wrap:focus-within { | |
| border-color: var(--border-focus); | |
| box-shadow: 0 0 0 3px rgba(46, 51, 197, 0.18); | |
| } | |
| .dda-stepper-wrap .dda-input-suffix-wrap { flex: 1; min-width: 0; } | |
| .dda-stepper-wrap input[type="number"] { | |
| border: none; | |
| border-radius: 0; | |
| background: transparent; | |
| } | |
| .dda-stepper-wrap input[type="number"]:focus { outline: none; box-shadow: none; } | |
| .dda-stepper-btn { | |
| flex: 0 0 auto; | |
| width: 2.25rem; | |
| margin: 0; | |
| padding: 0; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| border: none; | |
| background: transparent; | |
| color: var(--text-muted); | |
| font-size: 1.15rem; | |
| line-height: 1; | |
| font-family: var(--font-sans); | |
| cursor: pointer; | |
| transition: background var(--transition), color var(--transition); | |
| } | |
| .dda-stepper-btn:first-child { border-right: 1px solid var(--border); } | |
| .dda-stepper-btn:last-child { border-left: 1px solid var(--border); } | |
| .dda-stepper-btn:hover:not(:disabled) { background: var(--bg-hover); color: var(--accent-dim); } | |
| .dda-stepper-btn:active:not(:disabled) { background: var(--accent-glow); } | |
| .dda-stepper-btn:disabled { opacity: 0.35; cursor: not-allowed; } | |
| .dda-input-suffix-wrap { | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| } | |
| .dda-input-suffix-wrap input[type="number"] { | |
| padding-right: 2.75rem; | |
| /* Hide the native spinner — it renders at a browser-chosen width that | |
| collides with our own "px" suffix instead of sitting cleanly beside it; | |
| our own stepper buttons replace its increment/decrement role. */ | |
| -moz-appearance: textfield; | |
| } | |
| .dda-input-suffix-wrap input[type="number"]::-webkit-outer-spin-button, | |
| .dda-input-suffix-wrap input[type="number"]::-webkit-inner-spin-button { | |
| -webkit-appearance: none; | |
| margin: 0; | |
| } | |
| .dda-input-suffix-wrap input[type="number"]:focus + .dda-input-suffix { | |
| color: var(--accent-dim); | |
| } | |
| .dda-input-suffix { | |
| position: absolute; | |
| right: 1rem; | |
| top: 50%; | |
| transform: translateY(-50%); | |
| color: var(--text-dim); | |
| font-size: 0.8rem; | |
| font-weight: 500; | |
| letter-spacing: 0.02em; | |
| pointer-events: none; | |
| transition: color var(--transition); | |
| } | |
| .dda-modal { | |
| position: fixed; | |
| inset: 0; | |
| z-index: 1300; | |
| background: rgba(0, 0, 0, 0.55); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 1rem; | |
| } | |
| .dda-modal.hidden { display: none; } | |
| .dda-modal-panel { | |
| width: min(720px, 100%); | |
| max-height: 80vh; | |
| overflow: auto; | |
| } | |
| .dda-picker-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); | |
| gap: 0.65rem; | |
| padding: 0.5rem 0; | |
| } | |
| .dda-picker-item { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: stretch; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| background: var(--bg-elevated); | |
| cursor: pointer; | |
| padding: 0; | |
| overflow: hidden; | |
| text-align: left; | |
| color: var(--text); | |
| } | |
| .dda-picker-item:hover { border-color: var(--grad-start); } | |
| .dda-picker-item img { width: 100%; aspect-ratio: 1; object-fit: cover; } | |
| .dda-picker-item span { padding: 0.4rem 0.5rem; font-size: 0.75rem; } | |
| .dda-preflight-panel { width: min(560px, 100%); } | |
| .dda-preflight-list { | |
| list-style: none; | |
| margin: 0 0 1rem; | |
| padding: 0; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.5rem; | |
| } | |
| .dda-preflight-list li { | |
| padding: 0.65rem 0.85rem; | |
| border-radius: 6px; | |
| background: #fef3c7; | |
| color: #92400e; | |
| font-size: 0.88rem; | |
| line-height: 1.4; | |
| } | |
| .dda-preflight-list li.fail { | |
| background: #fef2f2; | |
| border: 1px solid #fecaca; | |
| color: #dc2626; | |
| } | |
| .dda-image-viewer-panel { | |
| width: min(1200px, 96vw); | |
| max-height: 92vh; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .dda-image-viewer-actions { | |
| display: flex; | |
| gap: 0.5rem; | |
| align-items: center; | |
| } | |
| .dda-image-viewer-body { | |
| padding: 0 1rem 1rem; | |
| overflow: auto; | |
| } | |
| .dda-image-viewer-wrap { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| min-height: 200px; | |
| background: var(--bg); | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| padding: 0.5rem; | |
| } | |
| #dda-image-viewer-img { | |
| max-width: 100%; | |
| max-height: 72vh; | |
| object-fit: contain; | |
| display: block; | |
| } | |
| .dda-image-viewer-status { min-height: 1.2rem; margin: 0 0 0.5rem; } | |
| .dda-image-viewer-status.dda-viewer-error { color: var(--danger, #dc2626); } | |
| .dda-image-viewer-meta { margin: 0 0 0.4rem; } | |
| .dda-viewer-meta-row { line-height: 1.5; } | |
| .dda-viewer-meta-row .dda-meta-sep { opacity: 0.5; margin: 0 0.15rem; } | |
| .dda-viewer-mode-bar { | |
| display: flex; | |
| gap: 0.35rem; | |
| margin: 0 0 0.65rem; | |
| } | |
| .dda-map-pane { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.5rem; | |
| min-height: 420px; | |
| } | |
| .dda-map-pane.hidden { display: none; } | |
| .dda-map-toolbar { | |
| display: flex; | |
| flex-wrap: wrap; | |
| align-items: center; | |
| gap: 0.65rem 0.9rem; | |
| padding: 0.55rem 0.7rem; | |
| background: var(--bg-elevated); | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| } | |
| .dda-map-field { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.4rem; | |
| font-size: 0.8rem; | |
| color: var(--text-muted); | |
| } | |
| .dda-map-field span { white-space: nowrap; } | |
| .dda-map-field select, | |
| .dda-map-xyz { | |
| min-width: 180px; | |
| padding: 0.28rem 0.45rem; | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| background: var(--bg-card); | |
| color: var(--text); | |
| font-size: 0.82rem; | |
| } | |
| .dda-map-xyz { min-width: 260px; flex: 1; } | |
| .dda-map-opacity input[type="range"] { width: 110px; vertical-align: middle; } | |
| .dda-map-opacity em { font-style: normal; color: var(--text); font-variant-numeric: tabular-nums; } | |
| .dda-map-status { min-height: 1.1rem; margin: 0; font-size: 0.8rem; } | |
| .dda-map-canvas { | |
| height: min(62vh, 640px); | |
| min-height: 360px; | |
| width: 100%; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| background: #1a1a2e; | |
| z-index: 1; | |
| } | |
| .dda-map-canvas.leaflet-container { | |
| height: min(62vh, 640px); | |
| } | |
| .dda-map-canvas .leaflet-ddaRaster-pane { | |
| z-index: 450; | |
| pointer-events: none; | |
| } | |
| .dda-map-canvas .leaflet-image-layer, | |
| .dda-map-canvas .dda-raster-overview { | |
| max-width: none ; | |
| max-height: none ; | |
| } | |
| #dda-result-map-pane .dda-map-canvas { height: min(58vh, 560px); } | |
| #dda-result-map-pane .dda-map-canvas.leaflet-container { height: min(58vh, 560px); } | |
| /* "Hide Details" collapses the stats row above the map — let the map grow | |
| into that freed space instead of leaving it blank. */ | |
| .result-modal.stats-hidden #dda-result-map-pane .dda-map-canvas, | |
| .result-modal.stats-hidden #dda-result-map-pane .dda-map-canvas.leaflet-container { | |
| height: min(80vh, 900px); | |
| } | |
| .dda-result-overlay { margin: 1rem 0; } | |
| .dda-result-img { max-width: 100%; border-radius: 8px; border: 1px solid var(--border); } | |
| .dda-regions-table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| font-size: 0.85rem; | |
| margin-top: 0.75rem; | |
| } | |
| .dda-regions-table th, .dda-regions-table td { | |
| border: 1px solid var(--border); | |
| padding: 0.35rem 0.5rem; | |
| text-align: left; | |
| } | |
| .dda-upload-form .location-row { margin-bottom: 0.5rem; } | |
| .dda-upload-form .form-group { | |
| margin-bottom: 0; | |
| min-width: 0; | |
| } | |
| .dda-upload-form .location-row > .form-group > label { | |
| display: block; | |
| align-items: unset; | |
| gap: 0; | |
| } | |
| .dda-upload-form .dda-datewrap { | |
| min-width: 0; | |
| width: 100%; | |
| } | |
| .dda-upload-progress { margin: 0.75rem 0 1rem; } | |
| .dda-progress-bar { | |
| height: 8px; | |
| background: var(--bg); | |
| border-radius: 4px; | |
| overflow: hidden; | |
| border: 1px solid var(--border); | |
| margin-bottom: 0.35rem; | |
| } | |
| .dda-progress-fill { | |
| height: 100%; | |
| width: 0%; | |
| background: linear-gradient(90deg, var(--grad-start), var(--grad-end, #10b981)); | |
| transition: width 0.15s ease; | |
| } | |
| .dda-hierarchy-wrap { | |
| margin-top: 1rem; | |
| padding-top: 0.75rem; | |
| border-top: 1px solid var(--border); | |
| } | |
| .dda-hierarchy-title { | |
| font-size: 0.75rem; | |
| text-transform: uppercase; | |
| letter-spacing: 0.04em; | |
| margin: 0 0 0.5rem; | |
| color: var(--text-muted, #888); | |
| } | |
| .dda-hierarchy-zone { margin-bottom: 0.35rem; } | |
| .dda-hierarchy-zone summary { | |
| cursor: pointer; | |
| font-size: 0.85rem; | |
| font-weight: 600; | |
| padding: 0.2rem 0; | |
| } | |
| .dda-hierarchy-list { | |
| list-style: none; | |
| margin: 0.25rem 0 0.5rem 0.75rem; | |
| padding: 0; | |
| font-size: 0.8rem; | |
| } | |
| .dda-hierarchy-village { padding: 0.15rem 0; } | |
| .regions-table tr.region-selected { background: rgba(16, 185, 129, 0.12); } | |
| .regions-table tr { cursor: pointer; } | |
| .dda-notify-wrap { position: relative; width: 100%; } | |
| .dda-notify-btn { | |
| position: relative; | |
| width: 100%; | |
| background: transparent; | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| padding: 0.5rem 0.7rem; | |
| cursor: pointer; | |
| color: var(--text-muted); | |
| display: flex; | |
| align-items: center; | |
| gap: 0.6rem; | |
| font-size: 0.85rem; | |
| transition: all var(--transition); | |
| } | |
| .dda-notify-btn:hover { background: var(--bg-hover); color: var(--text); } | |
| .dda-notify-badge { | |
| position: absolute; | |
| top: 4px; | |
| left: 22px; | |
| min-width: 16px; | |
| height: 16px; | |
| padding: 0 4px; | |
| border-radius: 999px; | |
| background: var(--danger, #dc2626); | |
| color: #fff; | |
| font-size: 10px; | |
| font-weight: 700; | |
| line-height: 16px; | |
| text-align: center; | |
| } | |
| .dda-notify-panel { | |
| /* position (fixed) + left/top/right/bottom are set inline by notifications.js | |
| so the panel anchors to the bell button's on-screen position — it must | |
| NOT rely on being positioned relative to .dda-sidebar-nav, which clips | |
| overflow for its own scrollbar. */ | |
| position: fixed; | |
| width: min(380px, 92vw); | |
| max-height: min(70vh, 480px); | |
| overflow-y: auto; | |
| background: var(--card, #fff); | |
| border: 1px solid var(--border); | |
| border-radius: 12px; | |
| box-shadow: 0 16px 40px rgba(0,0,0,0.18); | |
| z-index: 300; | |
| padding: 0.35rem; | |
| } | |
| /* Dims the page while the panel is open so it reads as a floating overlay | |
| rather than a layout glitch — the panel can land on top of a page's own | |
| secondary sidebar (e.g. the Library/Detect folder tree) since it opens | |
| near the nav sidebar regardless of what else is on screen. */ | |
| .dda-notify-backdrop { | |
| position: fixed; | |
| inset: 0; | |
| background: rgba(0, 0, 0, 0.25); | |
| z-index: 290; | |
| } | |
| .dda-notify-item { | |
| display: block; | |
| width: 100%; | |
| text-align: left; | |
| border: none; | |
| background: transparent; | |
| padding: 0.55rem 0.65rem; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| color: inherit; | |
| } | |
| .dda-notify-item:hover { background: rgba(0,0,0,0.04); } | |
| .dda-notify-item.unread { background: rgba(46, 51, 197, 0.06); } | |
| .dda-notify-item-title { display: block; font-size: 0.85rem; font-weight: 600; } | |
| .dda-notify-item-meta { display: block; font-size: 0.75rem; color: var(--text-muted, #888); margin-top: 0.15rem; } | |
| .dda-notify-empty { padding: 0.75rem; margin: 0; font-size: 0.85rem; } | |
| .dda-notify-email { margin-top: 0.35rem; width: 100%; max-width: 280px; } | |
| .dda-report-actions-cell { white-space: nowrap; } | |
| .dda-report-actions-cell .btn, .dda-report-actions-cell a.btn { margin-right: 0.25rem; margin-bottom: 0.25rem; } | |
| /* Standalone report page has no sidebar nav — full viewport interactive viewer. */ | |
| .dda-report-page.dda-app, | |
| #page-report-detail .dda-report-page { | |
| display: block; | |
| max-width: none; | |
| width: 100%; | |
| margin: 0; | |
| padding: 0; | |
| min-height: 100vh; | |
| height: auto; | |
| overflow: visible; | |
| background: var(--dm-bg, #f3f2f2); | |
| } | |
| .dda-report-page .dda-report-header { | |
| padding: 0.75rem 1rem; | |
| margin: 0; | |
| border-bottom: 1px solid var(--border); | |
| } | |
| .dda-report-page #result-modal.result-modal-backdrop { | |
| position: relative ; | |
| inset: auto ; | |
| z-index: 1 ; | |
| display: block ; | |
| background: var(--dm-bg, #f3f2f2) ; | |
| backdrop-filter: none ; | |
| overflow: visible ; | |
| min-height: 0; | |
| height: auto; | |
| } | |
| .dda-report-page #result-modal .result-modal { | |
| min-height: 0; | |
| height: auto; | |
| overflow: visible; | |
| box-shadow: none; | |
| } | |
| .dda-report-page #result-modal-close { | |
| display: none; | |
| } | |
| .dda-report-page #report-loading.hidden { display: none ; } | |
| .table-wrap { | |
| overflow-x: auto; | |
| width: 100%; | |
| } | |
| .dda-upload-type-error { | |
| color: var(--danger, #b91c1c); | |
| font-size: 0.85rem; | |
| margin: 0.5rem 0 0; | |
| } | |
| .dda-upload-type-error.hidden { display: none; } | |
| .dda-upload-file-list-wrap { | |
| margin-top: 0.75rem; | |
| overflow-x: auto; | |
| max-height: 220px; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| } | |
| .dda-upload-file-table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| font-size: 0.85rem; | |
| } | |
| .dda-upload-file-table th, | |
| .dda-upload-file-table td { | |
| padding: 0.4rem 0.55rem; | |
| border-bottom: 1px solid var(--border); | |
| text-align: left; | |
| vertical-align: middle; | |
| } | |
| .dda-upload-file-table .upload-server-name { | |
| width: 100%; | |
| min-width: 140px; | |
| font-size: 0.85rem; | |
| padding: 0.25rem 0.4rem; | |
| } | |
| .dda-lib-grid-actions { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 0.4rem; | |
| align-items: center; | |
| } | |
| .dda-card-img { position: relative; } | |
| .dda-card-select-wrap { | |
| position: absolute; | |
| top: 0.35rem; | |
| left: 0.35rem; | |
| z-index: 2; | |
| background: rgba(255,255,255,0.9); | |
| border-radius: 4px; | |
| padding: 0.1rem 0.2rem; | |
| line-height: 1; | |
| } | |
| .dda-card-filename { | |
| font-size: 0.85rem; | |
| font-weight: 600; | |
| } | |
| .dda-card-capture { | |
| font-size: 0.8rem; | |
| color: var(--text, #222); | |
| } | |
| .dda-upload-row { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); | |
| gap: 0.65rem 0.75rem; | |
| align-items: end; | |
| } | |
| .dda-header { | |
| display: flex; | |
| flex-wrap: wrap; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 1rem; | |
| margin-bottom: 1.25rem; | |
| } | |
| .dda-report-header { justify-content: space-between; } | |
| .dda-report-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; } | |
| .dda-report-stats { display: flex; flex-wrap: wrap; gap: 1rem 2rem; margin-top: 0.75rem; } | |
| .dda-stat .label { display: block; font-size: 0.75rem; color: var(--text-muted, #888); } | |
| .dda-stat .value { font-size: 1.25rem; font-weight: 700; } | |
| .dda-report-overlay { max-width: 100%; height: auto; border-radius: 8px; border: 1px solid var(--border); } | |
| .dda-report-email-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; } | |
| .dda-report-email-row input { flex: 1; min-width: 200px; } | |
| .dda-view-toolbar { | |
| display: flex; | |
| flex-wrap: wrap; | |
| align-items: center; | |
| gap: 0.35rem; | |
| margin: 0.5rem 0 0.75rem; | |
| } | |
| .dda-view-label { font-size: 0.8rem; color: var(--text-muted, #888); margin-right: 0.25rem; } | |
| .dda-view-btn { | |
| font-size: 0.78rem; | |
| padding: 0.25rem 0.55rem; | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| background: transparent; | |
| cursor: pointer; | |
| color: inherit; | |
| } | |
| .dda-view-btn.active { | |
| background: var(--grad-start, #2e33c5); | |
| color: #fff; | |
| border-color: transparent; | |
| } | |
| .dda-mode-slider .compare-handle { display: block; } | |
| .dda-mode-t1 .compare-handle, | |
| .dda-mode-t2 .compare-handle, | |
| .dda-mode-overlay .compare-handle { pointer-events: none; } | |
| .dda-review-bar { | |
| display: flex; | |
| flex-wrap: wrap; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 0.5rem; | |
| margin: 0.75rem 0; | |
| padding: 0.5rem 0; | |
| border-top: 1px solid var(--border); | |
| } | |
| .dda-review-actions { display: flex; flex-wrap: wrap; gap: 0.35rem; } | |
| .dda-review-btns { white-space: nowrap; } | |
| .dda-review-btns .btn { padding: 0.15rem 0.4rem; margin-right: 0.15rem; } | |
| .dda-review-btns .btn-review-ok.is-active { | |
| background: #15803d; | |
| border-color: #15803d; | |
| color: #fff; | |
| } | |
| .dda-review-btns .btn-review-fp.is-active { | |
| background: #b91c1c; | |
| border-color: #b91c1c; | |
| color: #fff; | |
| } | |
| .review-badge { | |
| font-size: 0.72rem; | |
| font-weight: 600; | |
| text-transform: capitalize; | |
| padding: 0.1rem 0.35rem; | |
| border-radius: 4px; | |
| } | |
| .review-pending { background: rgba(0,0,0,0.06); color: #666; } | |
| .review-confirmed { background: rgba(22, 163, 74, 0.15); color: #15803d; } | |
| .review-false-positive { background: rgba(220, 38, 38, 0.12); color: #b91c1c; } | |
| .review-submitted { background: rgba(46, 51, 197, 0.12); color: #2e33c5; } | |
| .highlight-pulse { animation: dda-pulse 1.2s ease-in-out 2; } | |
| @keyframes dda-pulse { | |
| 0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.5); } | |
| 50% { box-shadow: 0 0 0 6px rgba(16, 185, 129, 0); } | |
| } | |
| .regions-table-wrap { | |
| overflow-x: auto; | |
| max-width: 100%; | |
| } | |
| .regions-table-wrap .regions-table { | |
| min-width: 960px; | |
| } | |
| /* Modal side panel owns its own scroll; don't force a second min-width fight. */ | |
| .result-modal-side .regions-table-wrap .regions-table { | |
| min-width: 960px; | |
| } | |
| @media (max-width: 768px) { | |
| .dda-compare-slots { | |
| grid-template-columns: 1fr; | |
| } | |
| .dda-detect-options .form-group { | |
| min-width: 100%; | |
| } | |
| } | |
| /* ROI (region-of-interest) draw tool on the T2 preview */ | |
| #slot-t2-preview { position: relative; } | |
| #slot-t2-preview img.dda-slot-preview { cursor: crosshair; user-select: none; -webkit-user-drag: none; } | |
| .dda-roi-rect { | |
| position: absolute; | |
| border: 2px solid #ff3b3b; | |
| background: rgba(255, 59, 59, 0.15); | |
| box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.6); | |
| pointer-events: none; | |
| z-index: 5; | |
| border-radius: 2px; | |
| } | |
| .dda-roi-controls { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| margin: 6px 0; | |
| flex-wrap: wrap; | |
| } | |
| /* Polygon footprint layer over the compare viewer (sits under the bbox highlight) */ | |
| .region-polygon-layer { | |
| position: absolute; | |
| pointer-events: none; | |
| z-index: 4; | |
| overflow: visible; | |
| } | |
| /* Area chip shown when a region is located/selected on the compare viewer */ | |
| .region-area-label { | |
| position: absolute; | |
| z-index: 6; | |
| padding: 2px 6px; | |
| font-size: 12px; | |
| font-weight: 600; | |
| line-height: 1.3; | |
| color: #fff; | |
| background: rgba(20, 20, 20, 0.82); | |
| border-radius: 3px; | |
| white-space: nowrap; | |
| pointer-events: none; | |
| } | |
| /* Polygon / Box region-shape toggle in the detect options */ | |
| .dda-shape-toggle { | |
| display: inline-flex; | |
| border: 1px solid var(--border, #d0d5dd); | |
| border-radius: 6px; | |
| overflow: hidden; | |
| } | |
| .dda-shape-btn { | |
| padding: 6px 14px; | |
| font-size: 0.85rem; | |
| border: 0; | |
| background: transparent; | |
| color: inherit; | |
| cursor: pointer; | |
| transition: background 0.15s, color 0.15s; | |
| } | |
| .dda-shape-btn + .dda-shape-btn { border-left: 1px solid var(--border, #d0d5dd); } | |
| .dda-shape-btn:hover { background: rgba(46, 84, 150, 0.08); } | |
| .dda-shape-btn.is-active { background: #2e5496; color: #fff; } | |
| #tab-detect.dda-mode-automatic #dda-manual-compare, | |
| #tab-detect.dda-mode-automatic .dda-image-select, | |
| #tab-detect.dda-mode-automatic .dda-slot-pick { display: none; } | |
| #tab-detect.dda-mode-manual #dda-auto-compare { display: none; } | |
| .dda-mode-toggle { | |
| display: inline-flex; | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| overflow: hidden; | |
| } | |
| .dda-mode-btn { | |
| padding: 6px 14px; | |
| font-size: 0.85rem; | |
| border: 0; | |
| background: transparent; | |
| color: inherit; | |
| cursor: pointer; | |
| } | |
| .dda-mode-btn + .dda-mode-btn { border-left: 1px solid var(--border); } | |
| .dda-mode-btn:hover { background: rgba(46, 84, 150, 0.08); } | |
| .dda-mode-btn.is-active { background: #2e5496; color: #fff; } | |
| .dda-auto-compare { | |
| display: grid; | |
| grid-template-columns: minmax(220px, 1fr); | |
| gap: 0.35rem; | |
| margin: 0.75rem 0 0.25rem; | |
| } | |
| .dda-auto-compare select { | |
| width: 100%; | |
| max-width: 420px; | |
| padding: 0.35rem 0.5rem; | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| background: var(--bg-card); | |
| color: var(--text); | |
| } | |
| .dda-auto-schedule { | |
| margin: 0.15rem 0 0.5rem; | |
| font-size: 0.85rem; | |
| line-height: 1.35; | |
| } | |
| .dda-auto-schedule-controls { | |
| display: flex; | |
| flex-wrap: wrap; | |
| align-items: flex-end; | |
| gap: 0.65rem 1rem; | |
| margin: 0.5rem 0 0.25rem; | |
| } | |
| .dda-auto-field { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.2rem; | |
| font-size: 0.85rem; | |
| } | |
| .dda-auto-field input { | |
| min-width: 7rem; | |
| padding: 0.3rem 0.45rem; | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| background: var(--bg-card); | |
| color: var(--text); | |
| } | |
| .dda-shape-btn:hover { background: rgba(46, 84, 150, 0.08); } | |
| .dda-shape-btn.is-active { background: #2e5496; color: #fff; } | |
| .dda-area-pairs { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.75rem; | |
| max-height: 42vh; | |
| overflow-y: auto; | |
| } | |
| .dda-compare-pairs { max-height: 28vh; margin: 0.75rem 0 1rem; } | |
| .dda-area-pair { | |
| display: grid; | |
| grid-template-columns: minmax(140px, 1.2fr) 1fr 1fr auto; | |
| gap: 0.65rem 0.85rem; | |
| align-items: end; | |
| padding: 0.7rem 0.8rem; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| background: var(--bg-elevated); | |
| } | |
| .dda-area-pair-title { | |
| margin: 0; | |
| font-size: 0.92rem; | |
| font-weight: 600; | |
| } | |
| .dda-area-pair-meta { margin: 0.15rem 0 0; font-size: 0.78rem; } | |
| .dda-area-pair label { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.2rem; | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| } | |
| .dda-area-pair select { | |
| width: 100%; | |
| padding: 0.28rem 0.4rem; | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| background: var(--bg-card); | |
| color: var(--text); | |
| font-size: 0.8rem; | |
| } | |
| .dda-area-pair-overridden { font-size: 0.72rem; color: var(--grad-start); } | |
| @media (max-width: 900px) { | |
| .dda-area-pair { | |
| grid-template-columns: 1fr 1fr; | |
| } | |
| .dda-area-pair-head { grid-column: 1 / -1; } | |
| .dda-area-pair-actions { grid-column: 1 / -1; } | |
| } | |
| /* --------------------------------------------------------------------- | |
| Admin pages: Roles & Users, App Modules, Menu Management | |
| --------------------------------------------------------------------- */ | |
| .dda-admin-2col { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 1rem; | |
| align-items: start; | |
| } | |
| @media (max-width: 1100px) { | |
| .dda-admin-2col { grid-template-columns: 1fr; } | |
| } | |
| /* Roles & Users gets its own ratio — role hierarchy narrower, users table | |
| wider, so the table has real room to breathe on a full-width page. */ | |
| .dda-admin-2col-roles { grid-template-columns: 0.85fr 1.3fr; } | |
| @media (max-width: 1100px) { | |
| .dda-admin-2col-roles { grid-template-columns: 1fr; } | |
| } | |
| /* Dynamic role permissions — elements gated via shared.js's | |
| applyPermissionGating() against the Roles & Users permission matrix. | |
| Hidden elements reuse the existing global .hidden utility; this is just | |
| the "still visible but blocked" state for data-permission-mode="disable". */ | |
| .perm-disabled { opacity: 0.5; cursor: not-allowed; } | |
| /* My Profile page */ | |
| .dda-profile-summary { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 0.3rem; padding: 0.5rem 0 0.25rem; } | |
| .dda-profile-avatar { | |
| width: 72px; | |
| height: 72px; | |
| border-radius: 50%; | |
| background: var(--gradient); | |
| color: #fff; | |
| font-size: 1.7rem; | |
| font-weight: 700; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| margin-bottom: 0.4rem; | |
| } | |
| .dda-profile-badge { | |
| display: inline-block; | |
| margin: 0.35rem 0 0.9rem; | |
| padding: 0.25rem 0.75rem; | |
| border-radius: 999px; | |
| background: linear-gradient(135deg, rgba(46,51,197,0.12), rgba(207,32,64,0.08)); | |
| color: var(--grad-start); | |
| font-size: 0.78rem; | |
| font-weight: 600; | |
| } | |
| .dda-profile-meta { | |
| width: 100%; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.7rem; | |
| padding-top: 0.9rem; | |
| border-top: 1px solid var(--border); | |
| } | |
| .dda-profile-meta > div { display: flex; justify-content: space-between; align-items: center; font-size: 0.85rem; } | |
| .dda-profile-meta-label { color: var(--text-dim); } | |
| .dda-profile-meta-value { font-weight: 600; } | |
| /* Admin pages (Roles & Users / App Modules / Menu Management) use the full | |
| viewport width instead of the app's normal 1600px cap, so the wider | |
| tables/panels have as much room as the LMS reference layout does. */ | |
| .dda-app-full { max-width: none; } | |
| .dda-role-list { display: flex; flex-direction: column; gap: 0.65rem; } | |
| .dda-role-card { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 0.75rem; | |
| padding: 0.75rem 0.9rem; | |
| border: 1px solid var(--border); | |
| border-left: 3px solid var(--grad-start); | |
| border-radius: 8px; | |
| background: var(--bg-elevated); | |
| flex-wrap: wrap; | |
| } | |
| .dda-role-card-info { min-width: 0; } | |
| .dda-role-card-name { font-weight: 600; text-transform: capitalize; } | |
| .dda-role-card-name .dda-badge-system { | |
| margin-left: 0.4rem; | |
| font-size: 0.65rem; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| color: var(--text-dim); | |
| border: 1px solid var(--border); | |
| border-radius: 4px; | |
| padding: 0.05rem 0.35rem; | |
| } | |
| .dda-role-card-desc { font-size: 0.8rem; color: var(--text-muted); margin-top: 0.1rem; } | |
| .dda-role-card-actions { display: flex; gap: 0.35rem; flex-wrap: wrap; } | |
| .dda-role-card-name .dda-status-badge { margin-left: 0.4rem; vertical-align: middle; } | |
| .dda-role-card.is-inactive { opacity: 0.6; border-left-color: var(--text-dim); } | |
| .dda-perm-matrix { width: 100%; border-collapse: collapse; font-size: 0.85rem; } | |
| .dda-perm-matrix th, .dda-perm-matrix td { | |
| border: 1px solid var(--border); | |
| padding: 0.45rem 0.6rem; | |
| text-align: center; | |
| } | |
| .dda-perm-matrix th:first-child, .dda-perm-matrix td:first-child { text-align: left; } | |
| .dda-perm-matrix input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; } | |
| .dda-menu-list { display: flex; flex-direction: column; gap: 0.5rem; } | |
| .dda-menu-item-row { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.75rem; | |
| padding: 0.6rem 0.75rem; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| background: var(--bg-elevated); | |
| } | |
| .dda-menu-item-order { display: flex; flex-direction: column; gap: 0.15rem; } | |
| .dda-menu-item-order button { | |
| width: 22px; | |
| height: 18px; | |
| border: 1px solid var(--border); | |
| border-radius: 4px; | |
| background: var(--bg-card); | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| font-size: 0.7rem; | |
| line-height: 1; | |
| } | |
| .dda-menu-item-order button:hover:not(:disabled) { color: var(--grad-start); border-color: var(--grad-start); } | |
| .dda-menu-item-order button:disabled { opacity: 0.35; cursor: default; } | |
| .dda-menu-item-info { flex: 1 1 auto; min-width: 0; } | |
| .dda-menu-item-label { font-weight: 600; } | |
| .dda-menu-item-meta { font-size: 0.78rem; color: var(--text-muted); } | |
| .dda-menu-item-meta code { background: var(--bg); padding: 0.05rem 0.3rem; border-radius: 4px; } | |
| .dda-menu-item-actions { display: flex; gap: 0.35rem; flex-shrink: 0; } | |
| .dda-status-badge { | |
| font-size: 0.72rem; | |
| font-weight: 600; | |
| padding: 0.1rem 0.45rem; | |
| border-radius: 999px; | |
| } | |
| .dda-status-badge.is-active { background: rgba(16,185,129,0.12); color: #0d9488; } | |
| .dda-status-badge.is-inactive { background: rgba(220,38,38,0.1); color: var(--danger); } | |
| .dda-perm-matrix-actions { display: flex; gap: 0.5rem; margin-bottom: 0.75rem; } | |
| .dda-menu-item-row.is-child { margin-left: 2.25rem; } | |
| .dda-menu-item-icon { font-size: 1.1rem; margin-right: 0.3rem; } | |
| .dda-admin-side-panel { font-size: 0.85rem; color: var(--text-muted); line-height: 1.6; } | |
| .dda-admin-side-panel strong { color: var(--text); } | |
| .dda-admin-side-panel code { | |
| background: var(--bg); | |
| padding: 0.05rem 0.35rem; | |
| border-radius: 4px; | |
| color: var(--grad-start); | |
| } | |
| .dda-module-keys { display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.82rem; } | |
| .dda-module-keys code { background: var(--bg); padding: 0.15rem 0.5rem; border-radius: 4px; align-self: flex-start; } | |
| .dda-table-toolbar { display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; color: var(--text-muted); margin-bottom: 0.75rem; } | |
| .dda-table-toolbar select { padding: 0.25rem 0.4rem; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-card); color: var(--text); } | |
| /* --- Filters, dates, dropzone, folders master, run bar --- */ | |
| .dda-filter-bar { | |
| display: flex; | |
| flex-wrap: wrap; | |
| align-items: flex-end; | |
| gap: 0.65rem 0.85rem; | |
| margin: 0 0 1rem; | |
| padding: 0.75rem 0.85rem; | |
| border: 1px solid var(--border); | |
| border-radius: 10px; | |
| background: var(--bg); | |
| } | |
| .dda-filter-field { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.25rem; | |
| font-size: 0.78rem; | |
| font-weight: 600; | |
| color: var(--text-muted); | |
| } | |
| .dda-filter-field .dda-search, | |
| .dda-filter-field select, | |
| .dda-filter-field .dda-datewrap, | |
| input.dda-date-input:not(.dda-date-native) { | |
| min-width: 9.5rem; | |
| margin-bottom: 0; | |
| padding: 0.4rem 0.55rem; | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| background: var(--bg-card); | |
| color: var(--text); | |
| font-size: 0.88rem; | |
| font-weight: 500; | |
| } | |
| .dda-filter-field .dda-search { min-width: 14rem; } | |
| .dda-filter-meta { font-size: 0.85rem; white-space: nowrap; } | |
| time.dda-date { | |
| font-variant-numeric: tabular-nums; | |
| white-space: nowrap; | |
| } | |
| .dda-dropzone { | |
| margin-top: 0.75rem; | |
| padding: 1.15rem 1rem; | |
| border: 1.5px dashed var(--border); | |
| border-radius: 10px; | |
| background: var(--bg); | |
| text-align: center; | |
| transition: border-color 0.15s, background 0.15s; | |
| } | |
| .dda-dropzone.is-dragover { | |
| border-color: var(--grad-start); | |
| background: rgba(46, 84, 150, 0.08); | |
| } | |
| .dda-dropzone-title { margin: 0 0 0.25rem; font-weight: 650; } | |
| .dda-dropzone-actions { | |
| display: flex; | |
| justify-content: center; | |
| flex-wrap: wrap; | |
| gap: 0.5rem; | |
| margin: 0.75rem 0 0.35rem; | |
| } | |
| .dda-file-btn { | |
| position: relative; | |
| overflow: hidden; | |
| display: inline-flex; | |
| align-items: center; | |
| cursor: pointer; | |
| } | |
| .dda-file-btn input[type="file"] { | |
| position: absolute; | |
| inset: 0; | |
| opacity: 0; | |
| cursor: pointer; | |
| font-size: 0; | |
| } | |
| .dda-upload-summary { margin: 0.35rem 0 0; } | |
| .dda-tree-hint { font-size: 0.78rem; margin: 0 0 0.45rem; line-height: 1.35; } | |
| .dda-tree-node-btn.is-drop-target { | |
| outline: 2px dashed var(--grad-start); | |
| background: rgba(46, 84, 150, 0.1); | |
| color: var(--grad-start); | |
| } | |
| .dda-tree-menu { | |
| position: fixed; | |
| z-index: 80; | |
| min-width: 190px; | |
| padding: 0.3rem; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| background: var(--bg-card); | |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18); | |
| } | |
| .dda-tree-menu button { | |
| display: block; | |
| width: 100%; | |
| text-align: left; | |
| border: none; | |
| background: transparent; | |
| color: var(--text); | |
| padding: 0.4rem 0.6rem; | |
| border-radius: 6px; | |
| font-size: 0.86rem; | |
| cursor: pointer; | |
| } | |
| .dda-tree-menu button:hover { background: var(--bg-hover); } | |
| .dda-manage-panel { max-width: 640px; } | |
| .dda-run-bar { | |
| position: sticky; | |
| bottom: 0.6rem; | |
| z-index: 6; | |
| display: flex; | |
| flex-wrap: wrap; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 0.85rem 1.25rem; | |
| margin: 0.25rem 0 0.5rem; | |
| padding: 0.9rem 1.1rem; | |
| border: 1px solid var(--border); | |
| border-radius: 12px; | |
| background: var(--bg-card); | |
| box-shadow: 0 8px 28px rgba(0, 0, 0, 0.08); | |
| } | |
| .dda-run-bar-title { margin: 0 0 0.15rem; font-weight: 700; } | |
| .dda-run-bar .dim { margin: 0; } | |
| @media (max-width: 720px) { | |
| .dda-filter-field .dda-search, | |
| .dda-filter-field select, | |
| .dda-filter-field .dda-datewrap, | |
| input.dda-date-input:not(.dda-date-native), | |
| .dda-datewrap { min-width: 100%; } | |
| .dda-run-bar { position: static; } | |
| } | |
| /* --- Dashboard (Home) --- */ | |
| .dda-hero-row { | |
| display: flex; | |
| align-items: flex-start; | |
| justify-content: space-between; | |
| gap: 1rem; | |
| flex-wrap: wrap; | |
| } | |
| .dda-dash-hero-actions { display: flex; align-items: center; gap: 0.75rem; } | |
| .dda-dash-updated { font-size: 0.8rem; white-space: nowrap; } | |
| .dda-dash-filter-row { margin-top: 0.75rem; flex-wrap: wrap; } | |
| /* A distinct, bordered toolbar strip for the date filter — visually | |
| grouped instead of loose inline controls, so it reads as one control | |
| panel rather than stray fields sitting under the title. Label sits on | |
| its own line above the controls row so it never fights the taller | |
| labeled inputs for vertical alignment. */ | |
| .dda-dash-filter-bar { | |
| margin-top: 1rem; | |
| padding: 0.85rem 1rem 1rem; | |
| background: var(--bg-elevated); | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| } | |
| .dda-dash-filter-bar .card-header { margin-bottom: 0.85rem; } | |
| .dda-dash-filter-bar .card-header svg { flex-shrink: 0; color: var(--text-muted); } | |
| .dda-dash-filter-bar-controls { | |
| display: flex; | |
| align-items: flex-end; | |
| justify-content: space-between; | |
| flex-wrap: wrap; | |
| gap: 0.85rem; | |
| } | |
| .dda-dash-filter-range { display: flex; align-items: flex-end; gap: 0.65rem; } | |
| .dda-dash-filter-arrow { padding-bottom: 0.55rem; color: var(--text-dim); font-size: 0.9rem; } | |
| .dda-dash-filter-actions { display: flex; align-items: flex-end; gap: 0.6rem; } | |
| .dda-dash-section + .dda-dash-section { margin-top: 2rem; } | |
| .dda-dash-section-title { | |
| font-size: 0.78rem; | |
| font-weight: 700; | |
| letter-spacing: 0.08em; | |
| text-transform: uppercase; | |
| color: var(--text-dim, var(--text-muted)); | |
| margin: 0 0 0.75rem; | |
| padding-left: 0.15rem; | |
| } | |
| .dda-dash-overview-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); | |
| gap: 1.25rem; | |
| align-items: stretch; | |
| } | |
| .dda-dash-overview-grid .card { margin-top: 0; } | |
| .dda-dash-kpi-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); | |
| gap: 0.75rem; | |
| } | |
| a.stat-box.dda-dash-kpi { | |
| display: flex; | |
| flex-direction: column; | |
| text-decoration: none; | |
| border-top: 3px solid var(--accent); | |
| transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease; | |
| } | |
| a.stat-box.dda-dash-kpi:hover { | |
| border-color: var(--accent); | |
| transform: translateY(-2px); | |
| box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08); | |
| } | |
| a.stat-box.dda-dash-kpi:nth-child(6n+1) { border-top-color: var(--grad-start, var(--accent)); } | |
| a.stat-box.dda-dash-kpi:nth-child(6n+2) { border-top-color: var(--accent); } | |
| a.stat-box.dda-dash-kpi:nth-child(6n+3) { border-top-color: var(--success, var(--accent)); } | |
| a.stat-box.dda-dash-kpi:nth-child(6n+4) { border-top-color: var(--grad-mid, var(--accent)); } | |
| a.stat-box.dda-dash-kpi:nth-child(6n+5) { border-top-color: var(--accent-dim, var(--accent)); } | |
| a.stat-box.dda-dash-kpi:nth-child(6n+6) { border-top-color: var(--grad-end, var(--accent)); } | |
| .dda-dash-latest-row { display: flex; gap: 1.25rem; align-items: flex-start; flex-wrap: wrap; } | |
| .dda-dash-latest-thumb { | |
| width: 160px; | |
| height: 120px; | |
| object-fit: cover; | |
| border-radius: var(--radius-sm); | |
| border: 1px solid var(--border); | |
| flex-shrink: 0; | |
| } | |
| .dda-dash-latest-info h4 { margin: 0 0 0.25rem; } | |
| .dda-dash-latest-stats { display: flex; gap: 1.25rem; margin: 0.5rem 0 0.85rem; font-size: 0.88rem; color: var(--text-muted); } | |
| .dda-dash-latest-stats strong { color: var(--text); } | |
| .dda-dash-row-clickable { cursor: pointer; } | |
| .dda-dash-row-clickable:hover { background: var(--bg-hover, var(--bg-elevated)); } | |
| .dda-dash-row-active { background: var(--accent-glow); } | |
| .dda-dash-chart-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); | |
| gap: 1.25rem; | |
| } | |
| .dda-dash-chart-box-wide { grid-column: 1 / -1; } | |
| .dda-dash-chart-box { | |
| background: var(--bg-elevated); | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| padding: 1rem 1.1rem 0.6rem; | |
| } | |
| .dda-dash-chart-box h4 { | |
| margin: 0 0 0.75rem; | |
| font-size: 0.82rem; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| letter-spacing: 0.03em; | |
| color: var(--text-muted); | |
| } | |
| .dda-dash-compare-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | |
| gap: 1rem; | |
| margin: 0.75rem 0 1.25rem; | |
| padding: 1rem; | |
| background: var(--bg-elevated); | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| } | |
| .dda-dash-compare-col span.dim { display: block; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 0.35rem; } | |
| .dda-dash-compare-col h4 { margin: 0 0 0.2rem; } | |
| .dda-dash-compare-col p { margin: 0 0 0.35rem; } | |
| .dda-dash-delta { font-weight: 700; font-family: var(--font-mono); } | |
| .dda-dash-history-title { margin: 0 0 0.6rem; font-size: 0.95rem; } | |
| .dda-dash-class-line { font-size: 0.82rem; } | |
| /* Classification mini-bar — a compact stacked-proportion visual standing in | |
| for four separate table columns (confirmed/false positive/submitted/ | |
| unclassified), used across Region-wise, Village-wise, and Detection | |
| History wherever a full breakdown would otherwise need its own charts. */ | |
| .dda-class-bar { | |
| display: flex; | |
| width: 100%; | |
| min-width: 90px; | |
| height: 10px; | |
| border-radius: 5px; | |
| overflow: hidden; | |
| background: var(--bg-elevated); | |
| } | |
| .dda-class-seg { display: block; height: 100%; } | |
| .dda-class-confirmed { background: #16a34a; } | |
| .dda-class-fp { background: #dc2626; } | |
| .dda-class-submitted { background: #2563eb; } | |
| .dda-class-unclassified { background: #ca8a04; } | |
| .dda-class-bar-caption { | |
| display: block; | |
| font-size: 0.7rem; | |
| margin-top: 0.2rem; | |
| font-family: var(--font-mono); | |
| } | |
| .dda-accuracy-good { color: var(--success, #16a34a); font-weight: 700; } | |
| .dda-accuracy-mid { color: #ca8a04; font-weight: 700; } | |
| .dda-accuracy-low { color: var(--danger, #dc2626); font-weight: 700; } | |
| .dda-dash-summary { | |
| margin: 0 0 1.25rem; | |
| padding: 0.75rem 1rem; | |
| background: var(--accent-glow); | |
| border-left: 3px solid var(--accent); | |
| border-radius: 0 var(--radius-sm) var(--radius-sm) 0; | |
| font-size: 0.88rem; | |
| line-height: 1.5; | |
| } | |
| .dda-dash-compare-chart { margin: 0 0 1.25rem; } | |
| /* Change-type pill — colors match CHANGE_TYPE_COLORS in home.js exactly, | |
| one fixed meaning per color across every chart/table on the dashboard. */ | |
| .dda-changetype-pill { | |
| display: inline-block; | |
| padding: 0.15rem 0.55rem; | |
| border-radius: 999px; | |
| font-size: 0.72rem; | |
| font-weight: 600; | |
| white-space: nowrap; | |
| } | |
| .dda-changetype-New-Construction { background: rgba(249, 115, 22, 0.15); color: #c2410c; } | |
| .dda-changetype-Demolition { background: rgba(220, 38, 38, 0.15); color: #b91c1c; } | |
| .dda-changetype-Extension { background: rgba(37, 99, 235, 0.15); color: #1d4ed8; } | |
| .dda-changetype-Vegetation-Change { background: rgba(22, 163, 74, 0.15); color: #15803d; } | |
| .dda-changetype-Other { background: rgba(100, 116, 139, 0.15); color: #475569; } | |
| .dda-changetype-pill-group { display: flex; flex-wrap: wrap; gap: 0.3rem; } | |
| .dda-dash-latest-changetypes { margin: 0 0 0.85rem; } | |
| @media (max-width: 720px) { | |
| .dda-dash-latest-row { flex-direction: column; } | |
| .dda-dash-latest-thumb { width: 100%; height: 160px; } | |
| } | |
| /* ============================================================ | |
| Modernist dashboard theme (from the Claude Design redesign). | |
| Scoped entirely to #tab-home so the rest of the app keeps its | |
| existing look until/unless it gets redesigned too: flat | |
| surfaces, hairline dividers, sharp corners, one accent color, | |
| Archivo for headings and numbers. Tokens (--dm-*) are shared, | |
| declared once at :root above. | |
| ============================================================ */ | |
| #tab-home h1, | |
| #tab-home .dda-dash-section-title, | |
| #tab-home .card-title, | |
| #tab-home .dda-dash-chart-box h4, | |
| #tab-home .dda-dash-ranked-count, | |
| #tab-home .stat-box .value { | |
| font-family: var(--dm-font); | |
| } | |
| #tab-home h1#dda-home-greeting { font-weight: 800; letter-spacing: -0.01em; } | |
| #tab-home .dda-dash-section-title { | |
| font-size: 0.8rem; | |
| font-weight: 800; | |
| letter-spacing: 0.06em; | |
| border-bottom: 2px solid var(--dm-line); | |
| padding-bottom: 0.6rem; | |
| color: var(--dm-ink); | |
| } | |
| /* Flat, hairline-bordered surfaces instead of soft shadow cards */ | |
| #tab-home .card, | |
| #tab-home .dda-dash-chart-box, | |
| #tab-home .dda-dash-filter-bar, | |
| #tab-home .dda-dash-compare-grid { | |
| background: var(--dm-surface); | |
| border: 1px solid var(--dm-line); | |
| border-radius: 0; | |
| box-shadow: none; | |
| } | |
| #tab-home .dda-dash-chart-box h4 { font-weight: 700; color: var(--dm-ink); } | |
| #tab-home .dda-dash-filter-bar .card-header svg { color: var(--dm-accent); } | |
| #tab-home .dda-dash-filter-arrow { color: var(--dm-ink-dim); } | |
| #tab-home .dda-dash-latest-thumb { border-radius: 0; } | |
| #tab-home .dda-dash-summary { background: var(--dm-accent-100); border-left-color: var(--dm-accent); border-radius: 0; } | |
| /* Buttons — flat accent instead of the app-wide purple gradient, | |
| scoped to this page only so other pages are untouched. */ | |
| #tab-home .btn { border-radius: 0; font-family: var(--dm-font); font-weight: 700; } | |
| #tab-home .btn-primary { background: var(--dm-accent); } | |
| #tab-home .btn-primary:hover { background: var(--dm-accent-hover); filter: none; box-shadow: none; } | |
| #tab-home .btn-secondary { background: transparent; border-color: var(--dm-line); color: var(--dm-ink); } | |
| #tab-home .btn-secondary:hover { background: var(--dm-bg); border-color: var(--dm-line); } | |
| #tab-home .btn-ghost { color: var(--dm-accent); } | |
| #tab-home .btn-ghost:hover { background: var(--dm-accent-100); color: var(--dm-accent-hover); } | |
| /* Overview / Charts & Graphs / Breakdown / Image Library tab switch — a row | |
| of small flat cards (icon + label + sub-label) instead of a plain button | |
| toolbar, so each section reads as its own destination rather than one of | |
| several equal-weight pill options. */ | |
| #tab-home .dda-dash-tab-cards { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); | |
| gap: 0.75rem; | |
| margin-bottom: 1.5rem; | |
| } | |
| #tab-home .dda-dash-tab-card { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.75rem; | |
| padding: 0.9rem 1rem; | |
| background: var(--dm-surface); | |
| border: 1px solid var(--dm-line); | |
| border-radius: 0; | |
| cursor: pointer; | |
| text-align: left; | |
| transition: border-color 0.15s ease, background 0.15s ease; | |
| } | |
| #tab-home .dda-dash-tab-card:hover { background: var(--dm-bg); } | |
| #tab-home .dda-dash-tab-card-icon { | |
| flex-shrink: 0; | |
| width: 36px; | |
| height: 36px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: var(--dm-ink-muted); | |
| background: var(--dm-bg); | |
| border: 1px solid var(--dm-line); | |
| } | |
| #tab-home .dda-dash-tab-card-text { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; } | |
| #tab-home .dda-dash-tab-card-label { | |
| font-family: var(--dm-font); | |
| font-weight: 700; | |
| font-size: 0.92rem; | |
| color: var(--dm-ink); | |
| } | |
| #tab-home .dda-dash-tab-card-sub { | |
| font-size: 0.72rem; | |
| color: var(--dm-ink-muted); | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| #tab-home .dda-dash-tab-card.is-active { | |
| border-color: var(--dm-accent); | |
| background: var(--dm-accent-100); | |
| } | |
| #tab-home .dda-dash-tab-card.is-active .dda-dash-tab-card-icon { | |
| color: var(--dm-accent); | |
| border-color: var(--dm-accent); | |
| background: var(--dm-surface); | |
| } | |
| #tab-home .dda-dash-tab-card.is-active .dda-dash-tab-card-label { color: var(--dm-accent); } | |
| /* KPI grid — one shared hairline grid instead of individually | |
| bordered/shadowed tiles, each cell a plain flat surface. */ | |
| #tab-home .dda-dash-kpi-grid { | |
| display: grid; | |
| grid-template-columns: repeat(4, 1fr); | |
| gap: 1px; | |
| background: var(--dm-line); | |
| border: 1px solid var(--dm-line); | |
| } | |
| #tab-home a.stat-box.dda-dash-kpi { | |
| background: var(--dm-surface); | |
| border: none ; | |
| border-radius: 0; | |
| padding: 0.9rem 0.75rem; | |
| text-align: left; | |
| align-items: flex-start; | |
| transform: none ; | |
| box-shadow: none ; | |
| } | |
| #tab-home a.stat-box.dda-dash-kpi:hover { background: var(--dm-accent-100); } | |
| #tab-home .stat-box .value { | |
| font-weight: 800; | |
| font-size: 1.3rem; | |
| background: none; | |
| -webkit-background-clip: initial; | |
| background-clip: initial; | |
| -webkit-text-fill-color: var(--dm-ink); | |
| color: var(--dm-ink); | |
| white-space: normal; | |
| } | |
| #tab-home .stat-box .label { color: var(--dm-ink-muted); font-weight: 600; } | |
| @media (max-width: 900px) { #tab-home .dda-dash-kpi-grid { grid-template-columns: repeat(2, 1fr); } } | |
| @media (max-width: 480px) { #tab-home .dda-dash-kpi-grid { grid-template-columns: 1fr; } } | |
| /* Tables — uppercase hairline headers, no card wrapper needed per row */ | |
| #tab-home .dda-reports-table th { | |
| font-size: 0.68rem; | |
| letter-spacing: 0.06em; | |
| text-transform: uppercase; | |
| color: var(--dm-ink-muted); | |
| border-bottom: 2px solid var(--dm-line); | |
| } | |
| #tab-home .dda-reports-table td { border-bottom: 1px solid var(--dm-line); } | |
| #tab-home .dda-reports-table tbody tr:hover { background: var(--dm-bg); } | |
| #tab-home .dda-dash-row-active { background: var(--dm-accent-100) ; } | |
| #tab-home .dda-changetype-pill { border-radius: 2px; } | |
| /* Live detection-job banner — real job data (zone/village/method/ | |
| progress) from GET /api/dda/jobs, not a mockup placeholder. */ | |
| .dda-dash-live-banner { | |
| display: flex; | |
| align-items: center; | |
| gap: 1rem; | |
| flex-wrap: wrap; | |
| padding: 0.85rem 1.1rem; | |
| margin-bottom: 1.25rem; | |
| background: var(--dm-surface); | |
| border: 1px solid var(--dm-line); | |
| border-left: 3px solid var(--dm-accent); | |
| } | |
| .dda-dash-live-dot { | |
| width: 9px; | |
| height: 9px; | |
| border-radius: 50%; | |
| background: var(--dm-accent); | |
| flex-shrink: 0; | |
| animation: dda-dash-pulse 1.4s infinite; | |
| } | |
| @keyframes dda-dash-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } } | |
| .dda-dash-live-info { flex: 1; min-width: 220px; } | |
| .dda-dash-live-title { font-weight: 700; font-size: 0.9rem; color: var(--dm-ink); } | |
| .dda-dash-live-meta { font-size: 0.78rem; color: var(--dm-ink-muted); margin-top: 0.15rem; } | |
| .dda-dash-live-bar { width: 180px; height: 6px; background: var(--dm-line); flex-shrink: 0; } | |
| .dda-dash-live-bar-fill { height: 100%; background: var(--dm-accent); transition: width 0.6s ease; } | |
| .dda-dash-live-queued { | |
| font-size: 0.68rem; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| letter-spacing: 0.04em; | |
| border: 1px solid var(--dm-accent); | |
| color: var(--dm-accent); | |
| padding: 0.2rem 0.5rem; | |
| white-space: nowrap; | |
| } | |
| @media (max-width: 640px) { .dda-dash-live-bar { width: 100%; } } | |
| /* Ranked change-types list — replaces a second duplicate chart with | |
| the same totals the stacked "Change Types by Zone" bar already shows. */ | |
| .dda-dash-ranked-list { display: flex; flex-direction: column; gap: 0.55rem; } | |
| .dda-dash-ranked-row { display: flex; align-items: center; gap: 0.65rem; font-size: 0.85rem; } | |
| .dda-dash-ranked-swatch { width: 10px; height: 10px; flex-shrink: 0; } | |
| .dda-dash-ranked-label { flex: 1; color: var(--dm-ink); } | |
| .dda-dash-ranked-count { font-weight: 700; } | |
| .dda-dash-ranked-hint { font-size: 0.72rem; color: var(--dm-ink-dim); margin: -0.4rem 0 0.65rem; } | |
| /* Styled calendar date picker */ | |
| .dda-datewrap { | |
| position: relative; | |
| min-width: 0; | |
| width: 100%; | |
| overflow: visible; | |
| } | |
| .dda-filter-field .dda-datewrap { min-width: 9.5rem; } | |
| input.dda-date-input.dda-date-native, | |
| .dda-date-native { | |
| position: absolute ; | |
| left: 0; | |
| top: 0; | |
| width: 1px ; | |
| min-width: 0 ; | |
| max-width: 1px ; | |
| height: 1px ; | |
| margin: 0 ; | |
| padding: 0 ; | |
| border: 0 ; | |
| opacity: 0 ; | |
| pointer-events: none; | |
| clip: rect(0, 0, 0, 0); | |
| appearance: none; | |
| -webkit-appearance: none; | |
| } | |
| .dda-date-native:focus { | |
| outline: none ; | |
| box-shadow: none ; | |
| } | |
| .dda-date-trigger { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| width: 100%; | |
| min-width: 0; | |
| min-height: 2.35rem; | |
| padding: 0.4rem 0.7rem; | |
| overflow: hidden; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| background: var(--bg-card); | |
| color: var(--text); | |
| font: inherit; | |
| font-size: 0.88rem; | |
| font-weight: 500; | |
| cursor: pointer; | |
| text-align: left; | |
| } | |
| .dda-date-trigger:hover { border-color: var(--border-hover); } | |
| .dda-datewrap.is-open .dda-date-trigger { | |
| border-color: var(--border-focus); | |
| box-shadow: 0 0 0 3px var(--accent-glow); | |
| } | |
| .dda-date-placeholder { color: var(--text-dim); font-weight: 450; } | |
| .dda-date-trigger > span:not(.dda-date-clear) { | |
| min-width: 0; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| } | |
| .dda-date-clear { | |
| margin-left: auto; | |
| color: var(--text-dim); | |
| font-size: 1.1rem; | |
| line-height: 1; | |
| padding: 0 0.15rem; | |
| } | |
| .dda-date-clear:hover { color: var(--danger); } | |
| .dda-cal { | |
| display: none; | |
| position: fixed; | |
| z-index: 400; | |
| width: 280px; | |
| padding: 0.75rem; | |
| border: 1px solid var(--border); | |
| border-radius: 12px; | |
| background: var(--bg-card); | |
| box-shadow: 0 16px 40px rgba(26, 26, 46, 0.14); | |
| } | |
| .dda-datewrap.is-open .dda-cal { display: block; } | |
| .dda-cal-head { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 0.35rem; | |
| margin-bottom: 0.55rem; | |
| } | |
| .dda-cal-title { font-weight: 650; font-size: 0.92rem; } | |
| .dda-cal-period { | |
| display: flex; | |
| gap: 0.3rem; | |
| flex: 1; | |
| min-width: 0; | |
| } | |
| .dda-cal-month, .dda-cal-year { | |
| min-width: 0; | |
| flex: 1; | |
| height: 32px; | |
| padding: 0 0.35rem; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| background: var(--bg-card); | |
| color: var(--text); | |
| font: inherit; | |
| font-size: 0.82rem; | |
| font-weight: 600; | |
| } | |
| .dda-cal-nav { | |
| width: 32px; | |
| height: 32px; | |
| border: none; | |
| border-radius: 8px; | |
| background: var(--bg-surface); | |
| color: var(--text); | |
| font-size: 1.15rem; | |
| cursor: pointer; | |
| } | |
| .dda-cal-nav:hover { background: var(--bg-hover); } | |
| .dda-cal-dow, .dda-cal-grid { | |
| display: grid; | |
| grid-template-columns: repeat(7, 1fr); | |
| gap: 2px; | |
| text-align: center; | |
| } | |
| .dda-cal-dow { | |
| margin-bottom: 0.2rem; | |
| font-size: 0.68rem; | |
| font-weight: 650; | |
| color: var(--text-dim); | |
| letter-spacing: 0.04em; | |
| text-transform: uppercase; | |
| } | |
| .dda-cal-day { | |
| height: 32px; | |
| border: none; | |
| border-radius: 8px; | |
| background: transparent; | |
| color: var(--text); | |
| font-size: 0.82rem; | |
| cursor: pointer; | |
| } | |
| .dda-cal-day:hover:not(.is-empty) { background: var(--bg-hover); } | |
| .dda-cal-day.is-empty { cursor: default; } | |
| .dda-cal-day.is-today { box-shadow: inset 0 0 0 1.5px var(--grad-start); } | |
| .dda-cal-day.is-selected { | |
| background: var(--gradient); | |
| color: #fff; | |
| font-weight: 650; | |
| } | |
| .dda-cal-foot { display: flex; justify-content: flex-end; margin-top: 0.45rem; } | |
| .dda-cal-today { | |
| border: none; | |
| background: none; | |
| color: var(--grad-start); | |
| font-size: 0.8rem; | |
| font-weight: 600; | |
| cursor: pointer; | |
| } | |
| #dda-auto-run-at { | |
| min-width: 8.5rem; | |
| padding: 0.4rem 0.55rem; | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| background: var(--bg-card); | |
| color: var(--text); | |
| font: inherit; | |
| font-size: 0.88rem; | |
| } | |
| /* Logs */ | |
| .dda-logs-wrap { overflow: auto; max-height: min(70vh, 720px); } | |
| .dda-logs-table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| font-size: 0.82rem; | |
| } | |
| .dda-logs-table th, .dda-logs-table td { | |
| padding: 0.45rem 0.55rem; | |
| border-bottom: 1px solid var(--border); | |
| vertical-align: top; | |
| text-align: left; | |
| } | |
| .dda-logs-table th { color: var(--text-muted); font-size: 0.75rem; position: sticky; top: 0; background: var(--bg-card); } | |
| .dda-log-logger { color: var(--text-muted); white-space: nowrap; max-width: 12rem; overflow: hidden; text-overflow: ellipsis; } | |
| .dda-log-msg { font-family: var(--font-mono); font-size: 0.75rem; white-space: pre-wrap; word-break: break-word; } | |
| .dda-log-level { | |
| display: inline-block; | |
| min-width: 4.6rem; | |
| padding: 0.1rem 0.4rem; | |
| border-radius: 999px; | |
| font-size: 0.7rem; | |
| font-weight: 700; | |
| text-align: center; | |
| letter-spacing: 0.03em; | |
| } | |
| .dda-log-row.is-info .dda-log-level { background: rgba(46, 51, 197, 0.1); color: var(--grad-start); } | |
| .dda-log-row.is-warn .dda-log-level { background: rgba(217, 119, 6, 0.12); color: #b45309; } | |
| .dda-log-row.is-error .dda-log-level { background: var(--danger-glow); color: var(--danger); } | |
| .dda-log-row.is-debug .dda-log-level { background: var(--bg-hover); color: var(--text-dim); } | |
| /* Audit Log / Exception Log */ | |
| .dda-stat-cards { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); | |
| gap: 0.85rem; | |
| margin: 0 0 1rem; | |
| } | |
| .dda-stat-card { | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| background: var(--bg-card); | |
| padding: 0.9rem 1rem; | |
| text-align: center; | |
| } | |
| .dda-stat-card .dda-stat-icon { font-size: 1.1rem; line-height: 1; margin-bottom: 0.3rem; } | |
| .dda-stat-card .dda-stat-value { font-size: 1.6rem; font-weight: 700; line-height: 1.15; } | |
| .dda-stat-card .dda-stat-label { margin-top: 0.2rem; font-size: 0.76rem; color: var(--text-muted); } | |
| .dda-stat-card.is-danger .dda-stat-value { color: var(--danger); } | |
| .dda-stat-card.is-warn .dda-stat-value { color: #b45309; } | |
| .dda-badge { | |
| display: inline-block; | |
| padding: 0.1rem 0.5rem; | |
| border-radius: 999px; | |
| font-size: 0.72rem; | |
| font-weight: 700; | |
| letter-spacing: 0.02em; | |
| white-space: nowrap; | |
| } | |
| .dda-badge.is-ok { background: rgba(16, 130, 90, 0.12); color: #0f7a56; } | |
| .dda-badge.is-danger { background: var(--danger-glow); color: var(--danger); } | |
| .dda-badge.is-neutral { background: var(--bg-hover); color: var(--text-dim); } | |
| .dda-action-cell { font-family: var(--font-mono); font-size: 0.78rem; } | |
| .dda-otp-input, | |
| .dda-totp-input { | |
| letter-spacing: 0.28em; | |
| font-size: 1.15rem; | |
| font-weight: 650; | |
| font-variant-numeric: tabular-nums; | |
| text-align: center; | |
| } | |
| .dda-totp-qr { | |
| display: block; | |
| width: 180px; | |
| height: 180px; | |
| margin: 0.75rem 0; | |
| border-radius: 8px; | |
| border: 1px solid var(--border); | |
| } | |
| .dda-totp-secret code { | |
| font-size: 0.85rem; | |
| letter-spacing: 0.08em; | |
| } | |
| .dda-totp-form { margin-top: 0.75rem; display: flex; flex-direction: column; gap: 0.65rem; } | |
| /* --- Sign-in method tabs (Password / Mobile OTP) --------------------------- */ | |
| .dda-auth-tabs { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 0.25rem; | |
| padding: 0.25rem; | |
| background: var(--bg-elevated); | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| margin-bottom: 1.25rem; | |
| } | |
| .dda-auth-tab { | |
| appearance: none; | |
| border: 0; | |
| background: transparent; | |
| color: var(--text-muted); | |
| font: inherit; | |
| font-size: 0.85rem; | |
| font-weight: 600; | |
| padding: 0.55rem 0.75rem; | |
| border-radius: calc(var(--radius-sm) - 3px); | |
| cursor: pointer; | |
| transition: background var(--transition), color var(--transition), box-shadow var(--transition); | |
| } | |
| .dda-auth-tab:hover { color: var(--text); } | |
| .dda-auth-tab.is-active { | |
| background: var(--bg-card); | |
| color: var(--text); | |
| box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08); | |
| } | |
| /* --- Phone-number input: country code + local number, one seamless field --- */ | |
| .dda-phone-input { | |
| display: flex; | |
| align-items: stretch; | |
| gap: 0; | |
| background: var(--bg-elevated); | |
| border: 1px solid var(--border); | |
| border-radius: var(--radius-sm); | |
| transition: border-color var(--transition), box-shadow var(--transition); | |
| overflow: hidden; | |
| } | |
| .dda-phone-input:focus-within { | |
| border-color: var(--border-focus); | |
| box-shadow: 0 0 0 3px rgba(46, 51, 197, 0.18); | |
| } | |
| .dda-phone-input .dda-country-select, | |
| .dda-phone-input input[type="tel"] { | |
| border: 0; | |
| border-radius: 0; | |
| background: transparent; | |
| box-shadow: none; | |
| padding: 0.7rem 0.75rem; | |
| color: var(--text); | |
| font-family: var(--font-sans); | |
| font-size: 0.95rem; | |
| } | |
| .dda-phone-input .dda-country-select:focus, | |
| .dda-phone-input input[type="tel"]:focus { | |
| outline: none; | |
| box-shadow: none; | |
| border: 0; | |
| } | |
| .dda-phone-input .dda-country-select { | |
| flex: 0 0 auto; | |
| width: auto; | |
| min-width: 92px; | |
| max-width: 130px; | |
| padding-right: 0.4rem; | |
| border-right: 1px solid var(--border); | |
| background-color: transparent; | |
| font-variant-numeric: tabular-nums; | |
| cursor: pointer; | |
| } | |
| .dda-phone-input input[type="tel"] { | |
| flex: 1 1 auto; | |
| min-width: 0; | |
| letter-spacing: 0.02em; | |
| } | |
| .dda-phone-input.is-invalid { border-color: var(--danger); } | |