Make tab 3 reachable on mobile; restyle the tab bar; rename tabs
Browse filesGradio's .tab-container is flex-wrap:nowrap with overflow-x:hidden. At 375px tab 3
extends to 544px with no scroll, swipe or arrow to reach it -- a phone visitor could
not open the conformal risk control tab at all. Measured on the live DOM.
overflow-x:auto plus a narrow-viewport media query fixes it at any label length.
The active tab also differed from the inactive ones by colour alone: identical
font-weight, no fill, no border. Now three independent signals -- weight, fill, and a
real 3px underline. Selectors target .tab-container and [aria-selected] rather than the
svelte-* hash, which is regenerated on SDK rebuilds.
Renames: "Can it be fooled?" -> "Can We Fool the Model?"; "What can you actually
prove?" -> "What We'd Show an Auditor" -- the old title promised proof, the one word
that tab spends its length disclaiming. Numbers kept; the intro asserts the tabs are an
argument read in order.
Mirrors llm-wiki commit 0731cb9.
|
@@ -118,8 +118,42 @@ function() {
|
|
| 118 |
}
|
| 119 |
"""
|
| 120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
with gr.Blocks(title="Explainable & Auditable Alloy Defect Detection",
|
| 122 |
-
js=FORCE_LIGHT_THEME) as demo:
|
| 123 |
gr.Markdown(
|
| 124 |
"""
|
| 125 |
# Explainable & Auditable Alloy Defect Detection
|
|
@@ -136,7 +170,7 @@ with gr.Blocks(title="Explainable & Auditable Alloy Defect Detection",
|
|
| 136 |
guarantee, plus the lesson that audit tools need auditing before you trust them.
|
| 137 |
"""
|
| 138 |
)
|
| 139 |
-
with gr.Tab("1
|
| 140 |
gr.Markdown(
|
| 141 |
"Upload a micrograph (or pick an example below). The model predicts the "
|
| 142 |
"most likely defect class; the heatmap shows which pixels drove that "
|
|
@@ -163,7 +197,7 @@ with gr.Blocks(title="Explainable & Auditable Alloy Defect Detection",
|
|
| 163 |
run_button.click(predict, inputs=image_input, outputs=[overlay_output, label_output])
|
| 164 |
image_input.change(predict, inputs=image_input, outputs=[overlay_output, label_output])
|
| 165 |
|
| 166 |
-
with gr.Tab("2
|
| 167 |
gr.Markdown(SPURIOUS_SETUP)
|
| 168 |
gr.Image(
|
| 169 |
value="assets/spurious-correlation.png",
|
|
@@ -172,7 +206,7 @@ with gr.Blocks(title="Explainable & Auditable Alloy Defect Detection",
|
|
| 172 |
)
|
| 173 |
gr.Markdown(SPURIOUS_MARKDOWN)
|
| 174 |
|
| 175 |
-
with gr.Tab("3
|
| 176 |
gr.Markdown(
|
| 177 |
"""
|
| 178 |
### First: can we even tell whether the heatmap is faithful?
|
|
|
|
| 118 |
}
|
| 119 |
"""
|
| 120 |
|
| 121 |
+
# The tab bar is how a visitor discovers that tabs 2 and 3 exist at all, and those
|
| 122 |
+
# carry the whole contribution. Gradio's default marks the active tab by colour alone
|
| 123 |
+
# -- same weight, no fill, no border -- which is a weak cue and useless to anyone with
|
| 124 |
+
# red-green colour deficiency; and its container is flex-wrap:nowrap + overflow:hidden,
|
| 125 |
+
# so on a 375px phone tab 3 lands offscreen with no way to scroll to it. Below: three
|
| 126 |
+
# independent active-state signals (weight, fill, underline) and a scrollable bar.
|
| 127 |
+
# Targets .tab-container and aria-selected rather than Gradio's svelte-* hash, which is
|
| 128 |
+
# regenerated on every SDK rebuild and would silently stop matching.
|
| 129 |
+
TAB_CSS = """
|
| 130 |
+
.tab-container { gap: 6px; overflow-x: auto; scrollbar-width: none; }
|
| 131 |
+
.tab-container::-webkit-scrollbar { display: none; }
|
| 132 |
+
.tab-container button[role="tab"] {
|
| 133 |
+
flex: 0 0 auto;
|
| 134 |
+
white-space: nowrap;
|
| 135 |
+
font-size: 15px;
|
| 136 |
+
font-weight: 500;
|
| 137 |
+
padding: 11px 20px;
|
| 138 |
+
color: #52525b;
|
| 139 |
+
background: #f4f4f5;
|
| 140 |
+
border: 1px solid #e5e7eb;
|
| 141 |
+
border-radius: 8px 8px 0 0;
|
| 142 |
+
}
|
| 143 |
+
.tab-container button[role="tab"]:hover { background: #ececee; color: #27272a; }
|
| 144 |
+
.tab-container button[role="tab"][aria-selected="true"] {
|
| 145 |
+
font-weight: 600;
|
| 146 |
+
color: #9a3412;
|
| 147 |
+
background: #ffffff;
|
| 148 |
+
border-bottom: 3px solid #f97316;
|
| 149 |
+
}
|
| 150 |
+
@media (max-width: 640px) {
|
| 151 |
+
.tab-container button[role="tab"] { font-size: 13px; padding: 9px 12px; }
|
| 152 |
+
}
|
| 153 |
+
"""
|
| 154 |
+
|
| 155 |
with gr.Blocks(title="Explainable & Auditable Alloy Defect Detection",
|
| 156 |
+
css=TAB_CSS, js=FORCE_LIGHT_THEME) as demo:
|
| 157 |
gr.Markdown(
|
| 158 |
"""
|
| 159 |
# Explainable & Auditable Alloy Defect Detection
|
|
|
|
| 170 |
guarantee, plus the lesson that audit tools need auditing before you trust them.
|
| 171 |
"""
|
| 172 |
)
|
| 173 |
+
with gr.Tab("1 - Classify & Explain"):
|
| 174 |
gr.Markdown(
|
| 175 |
"Upload a micrograph (or pick an example below). The model predicts the "
|
| 176 |
"most likely defect class; the heatmap shows which pixels drove that "
|
|
|
|
| 197 |
run_button.click(predict, inputs=image_input, outputs=[overlay_output, label_output])
|
| 198 |
image_input.change(predict, inputs=image_input, outputs=[overlay_output, label_output])
|
| 199 |
|
| 200 |
+
with gr.Tab("2 - Can We Fool the Model?"):
|
| 201 |
gr.Markdown(SPURIOUS_SETUP)
|
| 202 |
gr.Image(
|
| 203 |
value="assets/spurious-correlation.png",
|
|
|
|
| 206 |
)
|
| 207 |
gr.Markdown(SPURIOUS_MARKDOWN)
|
| 208 |
|
| 209 |
+
with gr.Tab("3 - What We'd Show an Auditor"):
|
| 210 |
gr.Markdown(
|
| 211 |
"""
|
| 212 |
### First: can we even tell whether the heatmap is faithful?
|