/* ════════════════════════════════════════════════════════════════════ POWERGRID Document Auditor — Professional UI v3 Design System: Primary Navy : #00205B (PGCIL brand) Accent Green : #00843D (PGCIL brand) Accent Blue : #1565C0 (interactive) Surface : #F4F6FA Card : #FFFFFF Border : #E2E8F0 Text Primary : #0F1C2E Text Secondary: #4A6585 ════════════════════════════════════════════════════════════════════ */ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap'); /* ── CSS Custom Properties ──────────────────────────────────────── */ :root { --pg-navy: #00205B; --pg-navy-mid: #003087; --pg-navy-dark: #001540; --pg-green: #00843D; --pg-green-lt: #00A84F; --pg-blue: #1565C0; --pg-blue-lt: #1976D2; --surface: #F4F6FA; --surface-2: #EEF2F8; --card: #FFFFFF; --border: #E2E8F0; --border-focus: #1565C0; --text-1: #0F1C2E; --text-2: #4A6585; --text-3: #8BA0BB; --radius-sm: 6px; --radius-md: 10px; --radius-lg: 14px; --shadow-xs: 0 1px 3px rgba(0,32,91,0.08); --shadow-sm: 0 2px 8px rgba(0,32,91,0.10); --shadow-md: 0 4px 20px rgba(0,32,91,0.13); --transition: 0.15s ease; } /* ── Reset & Base ───────────────────────────────────────────────── */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } body, .gradio-container { background: var(--surface) !important; color: var(--text-1) !important; font-family: 'Inter', system-ui, -apple-system, sans-serif !important; font-size: 14px; line-height: 1.5; min-height: 100vh; -webkit-font-smoothing: antialiased; } .gradio-container > .main > .wrap { gap: 0 !important; padding: 0 !important; max-width: 100% !important; } footer { display: none !important; } /* ════════════════════════════════════════════════════════════════════ HEADER ════════════════════════════════════════════════════════════════════ */ #app-header { background: linear-gradient(135deg, var(--pg-navy-dark) 0%, var(--pg-navy) 50%, #003FAD 100%); border-bottom: 3px solid var(--pg-green); position: sticky; top: 0; z-index: 100; box-shadow: 0 4px 24px rgba(0,21,64,0.30); } #app-header-inner { display: flex; align-items: center; gap: 18px; padding: 12px 28px; max-width: 100%; } #app-header-logo { display: flex; align-items: center; justify-content: center; height: 52px; min-width: 52px; background: rgba(255,255,255,0.97); border-radius: var(--radius-md); flex-shrink: 0; padding: 6px 12px; box-shadow: 0 2px 10px rgba(0,0,0,0.20); } #app-header-logo img { height: 38px; width: auto; display: block; object-fit: contain; } #app-header-text h1 { color: #FFFFFF !important; font-size: 1.10rem !important; font-weight: 700 !important; margin: 0 !important; line-height: 1.25; letter-spacing: -0.01em; } #app-header-text p { color: rgba(163,200,255,0.88) !important; font-size: 0.70rem !important; margin: 2px 0 0 !important; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 500; } #app-header-badge { margin-left: auto; background: rgba(255,255,255,0.10); border: 1px solid rgba(255,255,255,0.18); border-radius: 20px; padding: 4px 14px; color: rgba(200,228,255,0.92); font-size: 0.66rem; font-weight: 600; letter-spacing: 0.08em; white-space: nowrap; backdrop-filter: blur(4px); } /* ════════════════════════════════════════════════════════════════════ MAIN CONTENT WRAPPER ════════════════════════════════════════════════════════════════════ */ /* Outer row wrapping both panels */ .gradio-container .row { gap: 16px !important; padding: 16px !important; align-items: flex-start !important; } /* ════════════════════════════════════════════════════════════════════ LEFT PANEL ════════════════════════════════════════════════════════════════════ */ #left-panel { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 0 !important; box-shadow: var(--shadow-sm); overflow: hidden; display: flex; flex-direction: column; gap: 0; } /* ── Section Labels ─────────────────────────────────────────────── */ .section-label { display: flex; align-items: center; gap: 7px; color: var(--pg-navy); font-size: 0.62rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; padding: 14px 16px 8px; border-bottom: 1px solid var(--border); margin-bottom: 0 !important; } .section-label::before { content: ''; display: inline-block; width: 3px; height: 12px; background: var(--pg-green); border-radius: 2px; flex-shrink: 0; } .section-divider { height: 1px; background: var(--border); margin: 0; border: none; } /* ── Left Panel inner spacing wrappers ─────────────────────────── */ #left-panel > .form, #left-panel > div > .form { padding: 0 !important; border: none !important; background: transparent !important; box-shadow: none !important; gap: 0 !important; } /* All Gradio components inside left panel get consistent padding */ #left-panel .gradio-checkbox, #left-panel .gradio-number, #left-panel .gradio-file { padding: 10px 16px !important; } /* ── File Upload — drop zone ────────────────────────────────────── */ #left-panel .upload-container, #left-panel [data-testid="file-upload"] { background: var(--surface) !important; border: 1.5px dashed #B8CCE0 !important; border-radius: var(--radius-md) !important; font-size: 0.79rem !important; color: var(--text-2) !important; transition: border-color var(--transition), background var(--transition); margin: 8px 16px !important; overflow: hidden !important; } #left-panel [data-testid="file-upload"]:hover { border-color: var(--pg-blue) !important; background: #EEF4FC !important; } /* ── Uploaded file preview (after a file is chosen) ─────────────── */ /* The outer wrapper Gradio renders once a file is uploaded */ #left-panel .file-preview { margin: 8px 16px !important; border: 1px solid var(--border) !important; border-radius: var(--radius-md) !important; background: var(--surface) !important; overflow: hidden !important; /* clips the child content — kills scrollbar */ max-width: 100% !important; box-sizing: border-box !important; } /* The inner upload-container div that Gradio renders inside preview */ #left-panel .file-preview .upload-container, #left-panel .file-preview [class*="upload"] { overflow: hidden !important; max-width: 100% !important; width: 100% !important; box-sizing: border-box !important; } /* The filename element — Gradio 6 uses .file-name with a svelte hash */ /* Target by class prefix since the hash changes between versions */ #left-panel [class*="file-name"] { overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important; max-width: 100% !important; width: 100% !important; /* Override Gradio's huge padding+font */ padding: 4px 8px !important; font-size: 0.78rem !important; word-break: normal !important; } /* The file-size element */ #left-panel [class*="file-size"] { padding: 2px 8px 4px !important; font-size: 0.70rem !important; color: var(--text-3) !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; max-width: 100% !important; } #left-panel .gradio-file > label { font-size: 0.72rem !important; font-weight: 600 !important; color: var(--text-2) !important; padding: 6px 16px 2px !important; text-transform: uppercase; letter-spacing: 0.06em; } /* ── Skip-page checkboxes ───────────────────────────────────────── */ .skip-cb { padding: 4px 16px 8px !important; } .skip-cb label { color: var(--text-2) !important; font-size: 0.76rem !important; } .skip-cb label span { color: var(--text-2) !important; } .skip-cb .info-text, .skip-cb [class*="description"], .skip-cb > .wrap > span:not([class*="label"]) { display: none !important; } .skip-cb:has(input:disabled) { position: relative; cursor: not-allowed; opacity: 0.55; } .skip-cb:has(input:disabled)::after { content: "Available for multi-page PDFs only"; position: absolute; left: 16px; top: calc(100% + 2px); background: var(--text-1); color: #fff; font-size: 0.68rem; padding: 5px 10px; border-radius: 5px; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity var(--transition); z-index: 999; box-shadow: var(--shadow-md); } .skip-cb:has(input:disabled):hover::after { opacity: 1; } /* ── Auto-align checkbox ────────────────────────────────────────── */ #left-panel .checkbox-group label { font-size: 0.79rem !important; color: var(--text-1) !important; font-weight: 500 !important; } #left-panel .gradio-checkbox { padding: 10px 16px !important; border-bottom: 1px solid var(--border) !important; } /* ── Compare Mode Radio ─────────────────────────────────────────── */ #compare-mode-radio { padding: 8px 16px 10px !important; } #compare-mode-radio .label-wrap { display: none !important; } #compare-mode-radio .wrap { display: flex !important; flex-direction: row !important; gap: 0 !important; background: var(--surface-2); border: 1px solid #C8D8EE; border-radius: var(--radius-sm); overflow: hidden !important; padding: 3px !important; width: 100% !important; box-shadow: inset 0 1px 3px rgba(0,32,91,0.08); } #compare-mode-radio .wrap label { flex: 1 1 0 !important; min-width: 0 !important; height: 28px !important; display: flex !important; align-items: center !important; justify-content: center !important; text-align: center !important; padding: 0 6px !important; margin: 0 !important; cursor: pointer; border-radius: 4px !important; transition: background var(--transition), color var(--transition); color: #4A6585 !important; background: transparent !important; } #compare-mode-radio .wrap label span { font-size: 0.72rem !important; font-weight: 600 !important; color: inherit !important; white-space: nowrap !important; pointer-events: none; } #compare-mode-radio .wrap label:has(input:checked) { background: var(--pg-navy) !important; color: #fff !important; box-shadow: 0 1px 4px rgba(0,32,91,0.28) !important; } #compare-mode-radio .wrap label:not(:has(input:checked)):hover { background: #dce8f8 !important; color: var(--pg-navy) !important; } #compare-mode-radio .wrap input[type=radio] { display: none !important; } /* ── Specific Page Inputs row ───────────────────────────────────── */ #specific-pages-row { padding: 4px 16px 10px !important; gap: 10px !important; align-items: flex-end !important; } #page-old-input, #page-new-input { flex: 1 1 0 !important; } #page-old-input label, #page-new-input label { font-size: 0.66rem !important; font-weight: 600 !important; color: var(--text-2) !important; text-transform: uppercase !important; letter-spacing: 0.07em !important; } #page-old-input input[type=number], #page-new-input input[type=number] { text-align: center !important; border: 1px solid #C0D4E8 !important; border-radius: var(--radius-sm) !important; font-size: 0.85rem !important; font-weight: 700 !important; color: var(--pg-navy) !important; background: var(--surface) !important; height: 36px !important; } #page-old-input input[type=number]:focus, #page-new-input input[type=number]:focus { border-color: var(--pg-blue) !important; box-shadow: 0 0 0 3px rgba(21,101,192,0.12) !important; outline: none !important; } /* ── RUN AUDIT Button ───────────────────────────────────────────── */ #run-btn { background: linear-gradient(135deg, var(--pg-green) 0%, var(--pg-green-lt) 100%) !important; border: none !important; border-radius: var(--radius-md) !important; color: #fff !important; font-weight: 700 !important; font-size: 0.88rem !important; letter-spacing: 0.04em; height: 44px !important; margin: 12px 16px !important; width: calc(100% - 32px) !important; box-shadow: 0 3px 12px rgba(0,132,61,0.35) !important; transition: box-shadow var(--transition), transform var(--transition); text-transform: uppercase; } #run-btn:hover { box-shadow: 0 5px 20px rgba(0,132,61,0.50) !important; transform: translateY(-1px) !important; } #run-btn:active { transform: translateY(0) !important; box-shadow: 0 2px 8px rgba(0,132,61,0.30) !important; } /* ── Fine-Tune Alignment D-Pad ──────────────────────────────────── */ #nudge-row-top, #nudge-row-bot { gap: 6px !important; justify-content: center !important; padding: 0 16px !important; margin: 0 !important; background: transparent !important; border: none !important; box-shadow: none !important; } #nudge-row-top { padding-top: 8px !important; } #nudge-row-bot { padding-bottom: 2px !important; } /* Keyboard-style arrow keys */ #nudge-up, #nudge-down, #nudge-left, #nudge-right { width: 40px !important; min-width: 40px !important; max-width: 40px !important; height: 40px !important; padding: 0 !important; font-size: 0.95rem !important; border-radius: 8px !important; background: var(--card) !important; border: 1px solid #C0D4E8 !important; color: var(--pg-navy) !important; box-shadow: 0 3px 0 #9AB5CE, 0 4px 8px rgba(0,32,91,0.10) !important; transition: box-shadow 0.07s, transform 0.07s, background var(--transition); flex-shrink: 0 !important; font-weight: 700 !important; } #nudge-up:hover, #nudge-down:hover, #nudge-left:hover, #nudge-right:hover { background: #E8F0FC !important; border-color: var(--pg-navy) !important; box-shadow: 0 4px 0 var(--pg-navy), 0 6px 14px rgba(0,32,91,0.16) !important; transform: translateY(-1px); } #nudge-up:active, #nudge-down:active, #nudge-left:active, #nudge-right:active { transform: translateY(3px) !important; box-shadow: 0 0 0 #9AB5CE, 0 1px 3px rgba(0,32,91,0.10) !important; background: #C5D8EE !important; } /* Tip text below D-pad */ .nudge-tip { font-size: 0.66rem !important; color: var(--text-3) !important; margin: 4px 16px 8px !important; font-style: italic; text-align: center; line-height: 1.5; } /* Step / Scale inputs */ #nudge-step, #nudge-scale { padding: 6px 16px !important; } #nudge-step input[type=number], #nudge-scale input[type=number] { text-align: center !important; border: 1px solid #C0D4E8 !important; border-radius: var(--radius-sm) !important; font-size: 0.82rem !important; color: var(--pg-navy) !important; background: var(--surface) !important; transition: border-color var(--transition); } #nudge-step input[type=number]:focus, #nudge-scale input[type=number]:focus { border-color: var(--pg-blue) !important; outline: none !important; box-shadow: 0 0 0 3px rgba(21,101,192,0.12) !important; } #nudge-step label, #nudge-scale label { font-size: 0.67rem !important; font-weight: 600 !important; color: var(--text-2) !important; text-transform: uppercase !important; letter-spacing: 0.07em !important; } /* Offset readout */ #nudge-readout-wrap { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 12px; font-family: 'SF Mono', 'Fira Code', 'Courier New', monospace; font-size: 0.72rem; color: var(--pg-navy); text-align: left; line-height: 1.9; margin: 4px 16px 12px; letter-spacing: 0.02em; } /* ════════════════════════════════════════════════════════════════════ RIGHT PANEL ════════════════════════════════════════════════════════════════════ */ #right-panel { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 16px !important; box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: 12px; } /* ── Toolbar ────────────────────────────────────────────────────── */ #toolbar-row { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 5px 8px; align-items: center !important; flex-wrap: nowrap !important; gap: 6px !important; min-height: 44px; box-shadow: var(--shadow-xs); overflow: visible; } /* Gradio wraps each Row child in a div — make the radio wrapper flex-shrink properly */ #toolbar-row > div { display: flex !important; align-items: center !important; min-width: 0 !important; } #toolbar-row > div:has(#view-mode-radio) { flex: 1 1 auto !important; min-width: 0 !important; overflow: hidden; } .toolbar-sep { width: 1px; height: 24px; background: var(--border); flex-shrink: 0; align-self: center; margin: 0 1px; } /* ── Segmented view-mode control ─────────────────────────────────── */ #view-mode-radio { flex: 1 1 auto !important; min-width: 0 !important; overflow: visible; /* Kill any top margin/padding Gradio adds for label space */ padding-top: 0 !important; margin-top: 0 !important; } /* Hide label — belt-and-suspenders: show_label=False in Python + CSS */ #view-mode-radio .label-wrap, #view-mode-radio [data-testid="block-label"], #view-mode-radio > label { display: none !important; } /* The pill container — fills the full width of the radio component */ #view-mode-radio .wrap { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; gap: 2px !important; background: var(--surface-2); border: 1px solid #C8D8EE; border-radius: var(--radius-sm); overflow: hidden !important; padding: 3px !important; width: 100% !important; box-sizing: border-box !important; box-shadow: inset 0 1px 3px rgba(0,32,91,0.08); margin: 0 !important; } /* Each pill — equal thirds, fixed height, centered text */ #view-mode-radio .wrap label { flex: 1 1 0 !important; min-width: 0 !important; height: 30px !important; display: flex !important; align-items: center !important; justify-content: center !important; text-align: center !important; padding: 0 6px !important; margin: 0 !important; cursor: pointer; border-radius: 4px !important; transition: background var(--transition), color var(--transition), box-shadow var(--transition); color: #4A6585 !important; background: transparent !important; overflow: hidden !important; } /* The text node — Gradio wraps it in a span */ #view-mode-radio .wrap label span { font-size: 0.73rem !important; font-weight: 600 !important; color: inherit !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; line-height: 1 !important; pointer-events: none; } /* Selected pill → navy */ #view-mode-radio .wrap label:has(input:checked) { background: var(--pg-navy) !important; color: #ffffff !important; box-shadow: 0 1px 4px rgba(0,32,91,0.28) !important; } /* Hover (unselected) */ #view-mode-radio .wrap label:not(:has(input:checked)):hover { background: #dce8f8 !important; color: var(--pg-navy) !important; } #view-mode-radio .wrap input[type=radio] { display: none !important; } /* Rotation buttons */ #rot-left, #rot-right { width: 36px !important; min-width: 36px !important; max-width: 36px !important; height: 36px !important; padding: 0 !important; font-size: 1.10rem !important; border-radius: var(--radius-sm) !important; background: var(--card) !important; border: 1px solid #C8D8EE !important; color: var(--pg-navy) !important; flex-shrink: 0 !important; transition: background var(--transition), border-color var(--transition), box-shadow var(--transition); box-shadow: var(--shadow-xs); } #rot-left:hover, #rot-right:hover { background: #E8F0FC !important; border-color: var(--pg-blue) !important; box-shadow: 0 0 0 3px rgba(21,101,192,0.12) !important; } /* ── Page slider ─────────────────────────────────────────────────── */ #page-slider { padding: 4px 2px 2px !important; margin: 0 !important; } /* Label row: "Page 1 / 5" */ #page-slider .label-wrap { display: flex !important; align-items: center !important; gap: 6px; margin-bottom: 2px !important; } #page-slider .label-wrap span { font-size: 0.72rem !important; font-weight: 700 !important; color: var(--text-2) !important; text-transform: uppercase !important; letter-spacing: 0.07em !important; } /* The track */ #page-slider input[type=range] { accent-color: var(--pg-navy) !important; height: 4px; cursor: pointer; } /* Number box beside the slider */ #page-slider .number-wrap input, #page-slider input[type=number] { width: 48px !important; text-align: center !important; font-size: 0.78rem !important; font-weight: 600 !important; color: var(--pg-navy) !important; border: 1px solid #C8D8EE !important; border-radius: var(--radius-sm) !important; background: var(--surface) !important; padding: 2px 4px !important; } /* ── Result Image ───────────────────────────────────────────────── */ #result-image { border-radius: var(--radius-md); overflow: hidden; border: 1px solid var(--border); box-shadow: var(--shadow-sm); background: var(--surface); } #result-image > .label-wrap { display: none !important; } #result-image .image-container { border-radius: var(--radius-md); overflow: hidden; } /* ── Legend Bar ─────────────────────────────────────────────────── */ #legend-bar { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 8px 16px; flex-wrap: wrap !important; gap: 12px !important; box-shadow: var(--shadow-xs); } /* ── Download area ──────────────────────────────────────────────── */ #right-panel .file-preview, #right-panel [data-testid="file"] { border: 1px solid var(--border) !important; border-radius: var(--radius-md) !important; background: var(--surface) !important; box-shadow: var(--shadow-xs) !important; transition: box-shadow var(--transition); } #right-panel .file-preview:hover, #right-panel [data-testid="file"]:hover { box-shadow: var(--shadow-sm) !important; } /* ════════════════════════════════════════════════════════════════════ GLOBAL GRADIO OVERRIDES — clean up noisy defaults ════════════════════════════════════════════════════════════════════ */ /* Remove double borders on column/row containers */ .gradio-container .block { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; } /* Keep panel overrides intact */ #left-panel.block, #right-panel.block { border: 1px solid var(--border) !important; background: var(--card) !important; box-shadow: var(--shadow-sm) !important; } /* Gradio checkbox styling */ .gradio-checkbox input[type=checkbox] { accent-color: var(--pg-green) !important; width: 15px; height: 15px; } /* Gradio Number input spinners */ .gradio-number input[type=number]::-webkit-inner-spin-button, .gradio-number input[type=number]::-webkit-outer-spin-button { opacity: 0.5; } /* Scrollbar styling (webkit) */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: var(--surface-2); border-radius: 3px; } ::-webkit-scrollbar-thumb { background: #B0C4DA; border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: #7A9DC0; } /* ── Region selection widgets ───────────────────────────────── */ #page-compare-mode-radio .wrap { flex-direction: row !important; gap: 4px !important; padding: 3px !important; background: var(--surface-2); border: 1px solid #C8D8EE; border-radius: var(--radius-sm); } #page-compare-mode-radio .wrap label { flex: 1 1 0 !important; height: 28px !important; display: flex !important; align-items: center !important; justify-content: center !important; font-size: 0.72rem !important; font-weight: 600 !important; border-radius: 4px !important; cursor: pointer; color: #4A6585 !important; background: transparent !important; transition: background var(--transition), color var(--transition); } #page-compare-mode-radio .wrap label:has(input:checked) { background: var(--pg-navy) !important; color: #ffffff !important; } #page-compare-mode-radio .wrap input[type=radio] { display: none !important; } /* Region selector — image + overlay canvas */ #region-page-img { border: 2px dashed #7A9DC0 !important; border-radius: var(--radius-md) !important; background: #f0f4f8 !important; margin-top: 4px !important; } #region-page-img .image-container { position: relative !important; } #region-draw-overlay { position: absolute; cursor: crosshair; z-index: 10; } /* Hide the coords bridge textbox but keep it in the DOM */ .region-coords-hidden { height: 0 !important; min-height: 0 !important; overflow: hidden !important; padding: 0 !important; margin: 0 !important; border: none !important; opacity: 0 !important; pointer-events: none !important; } .region-coords-hidden textarea { display: none !important; } #clear-region-btn { margin-top: 4px; } #region-readout { font-size: 0.71rem; color: #4A6585; background: var(--surface); border: 1px solid #C8D8EE; border-radius: var(--radius-sm); padding: 5px 8px; margin: 4px 0; min-height: 28px; line-height: 1.4; }