"""Custom CSS for the verdict card. Kept in its own module so it can be imported without pulling in gradio (handy for tests). """ CUSTOM_CSS = """ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap'); :root { --gw-bg: #fafaf7; --gw-card-bg: #ffffff; --gw-text: #1a1f1a; --gw-muted: #5b6961; --gw-border: #e7eae5; --gw-good: #2f9e58; --gw-good-soft: #e6f6ec; --gw-okay: #c79100; --gw-okay-soft: #fff5d9; --gw-warn: #d97706; --gw-warn-soft: #ffeacc; --gw-bad: #c44545; --gw-bad-soft: #fde2e2; --gw-legal: #5b21b6; --gw-legal-soft: #ede9fe; --gw-shadow: 0 1px 2px rgba(0,0,0,.04), 0 8px 24px rgba(0,0,0,.06); } /* ---------- top-level layout ---------- */ .gw-app { font-family: Inter, system-ui, -apple-system, sans-serif; color: var(--gw-text); } /* Header */ .gw-pageheader { padding: 12px 0 4px; } .gw-pageheader h1 { margin: 0; font-size: 28px; letter-spacing: -.02em; font-weight: 800; } .gw-pageheader p { margin: 4px 0 0; color: var(--gw-muted); font-size: 15px; } /* ---------- placeholder ---------- */ .gw-placeholder { border: 1px dashed var(--gw-border); background: linear-gradient(180deg, #ffffff 0%, #f7faf6 100%); border-radius: 16px; padding: 32px 24px; text-align: center; color: var(--gw-muted); } .gw-placeholder__emoji { font-size: 56px; line-height: 1; margin-bottom: 8px; } .gw-placeholder h2 { margin: 8px 0 4px; color: var(--gw-text); font-weight: 700; font-size: 20px; } .gw-placeholder p { margin: 4px 0; font-size: 14px; } .gw-placeholder__hint { font-size: 13px; max-width: 38ch; margin: 12px auto 0; } /* ---------- card ---------- */ .gw-card { background: var(--gw-card-bg); border-radius: 18px; box-shadow: var(--gw-shadow); overflow: hidden; margin: 0; } .gw-card--neutral .gw-hero--neutral { background: linear-gradient(135deg, #f1f3f0, #e7eae5); color: var(--gw-text); } .gw-card--green .gw-hero { background: linear-gradient(135deg, #2f9e58, #1f7a44); color: white; } .gw-card--greenwasher .gw-hero { background: linear-gradient(135deg, #f59f00, #c97a00); color: white; } .gw-card--hazard .gw-hero { background: linear-gradient(135deg, #c44545, #8e2929); color: white; } /* ---------- hero ---------- */ .gw-hero { display: flex; align-items: center; gap: 18px; padding: 22px 24px; flex-wrap: wrap; } .gw-hero__emoji { font-size: 56px; line-height: 1; flex: 0 0 auto; filter: drop-shadow(0 2px 6px rgba(0,0,0,.15)); } .gw-hero__text { flex: 1 1 220px; min-width: 0; } .gw-hero__label { font-size: 26px; font-weight: 800; letter-spacing: -.01em; line-height: 1.1; } .gw-hero__tagline { margin-top: 4px; font-size: 14px; opacity: .9; } .gw-hero__meta { display: flex; gap: 16px; flex: 0 0 auto; } .gw-hero__metaitem { text-align: right; min-width: 70px; } .gw-hero__metalabel { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; opacity: .8; } .gw-hero__metavalue { font-size: 22px; font-weight: 700; } /* ---------- why ---------- */ .gw-why { padding: 14px 24px; border-bottom: 1px solid var(--gw-border); font-size: 14px; color: var(--gw-text); margin: 0; } .gw-why strong { font-weight: 700; } /* ---------- badges ---------- */ .gw-badges { display: flex; flex-wrap: wrap; gap: 8px; padding: 14px 24px 0; } .gw-badge { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px; font-size: 12px; font-weight: 600; } .gw-badge--warn { background: var(--gw-warn-soft); color: var(--gw-warn); } .gw-badge--info { background: #e0f2fe; color: #075985; } .gw-badge--legal { background: var(--gw-legal-soft); color: var(--gw-legal); } /* ---------- section ---------- */ .gw-section { padding: 16px 24px; border-top: 1px solid var(--gw-border); } .gw-section__title { margin: 0 0 12px; font-size: 13px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--gw-muted); } .gw-section--legal { background: var(--gw-legal-soft); } .gw-section--legal .gw-section__title { color: var(--gw-legal); } /* ---------- identification ---------- */ .gw-id { display: grid; gap: 6px; } .gw-id__row { display: flex; gap: 12px; align-items: center; font-size: 14px; } .gw-id__label { color: var(--gw-muted); min-width: 110px; font-weight: 600; } .gw-id__value { color: var(--gw-text); } .gw-id__meta { color: var(--gw-muted); font-style: italic; } .gw-warning { margin-top: 12px; padding: 10px 12px; background: var(--gw-warn-soft); border-left: 3px solid var(--gw-warn); border-radius: 6px; font-size: 13px; color: #7a4400; } /* ---------- chip ---------- */ .gw-chip { display: inline-block; padding: 2px 10px; border-radius: 999px; background: #f1f5f0; color: var(--gw-text); font-size: 12px; font-weight: 600; } .gw-chip--mono { font-family: ui-monospace, SFMono-Regular, monospace; } .gw-chips { display: flex; flex-wrap: wrap; gap: 6px; } /* ---------- axes ---------- */ .gw-axes { display: grid; gap: 14px; } .gw-axis {} .gw-axis__head { display: flex; justify-content: space-between; align-items: baseline; } .gw-axis__name { font-size: 14px; font-weight: 600; } .gw-axis__score { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; } .gw-axis__score-suffix { font-size: 12px; color: var(--gw-muted); font-weight: 500; } .gw-axis__track { margin-top: 6px; height: 10px; background: #f1f3f0; border-radius: 999px; overflow: hidden; position: relative; } .gw-axis__fill { height: 100%; border-radius: 999px; transition: width .4s ease; } .gw-axis__fill--good { background: linear-gradient(90deg, #2f9e58, #4cc473); } .gw-axis__fill--okay { background: linear-gradient(90deg, #f59f00, #ffc850); } .gw-axis__fill--warn { background: linear-gradient(90deg, #d97706, #fb923c); } .gw-axis__fill--bad { background: linear-gradient(90deg, #c44545, #ef6b6b); } .gw-axis__band { margin-top: 4px; font-size: 12px; color: var(--gw-muted); } /* ---------- reasons ---------- */ .gw-reasons { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; } .gw-reason { display: flex; gap: 12px; align-items: flex-start; padding: 12px; border: 1px solid var(--gw-border); border-radius: 12px; background: #fcfdfb; } .gw-reason__title { font-weight: 600; font-size: 14px; } .gw-reason__body { margin: 4px 0 0; font-size: 13px; color: var(--gw-muted); } .gw-pill { flex: 0 0 auto; padding: 4px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap; } .gw-pill--low { background: #e0f2fe; color: #075985; } .gw-pill--moderate { background: var(--gw-okay-soft); color: #7a5300; } .gw-pill--high { background: var(--gw-warn-soft); color: var(--gw-warn); } .gw-pill--very-high { background: var(--gw-bad-soft); color: var(--gw-bad); } .gw-pill--critical { background: #1a1a1a; color: #fff; } /* ---------- sources ---------- */ .gw-sources { margin: 0; padding-left: 18px; font-size: 13px; } .gw-sources li { margin: 4px 0; } .gw-sources a { color: var(--gw-good); text-decoration: none; word-break: break-all; } .gw-sources a:hover { text-decoration: underline; } /* ---------- footer ---------- */ .gw-footer { padding: 14px 24px; border-top: 1px solid var(--gw-border); font-size: 12px; color: var(--gw-muted); font-style: italic; background: #fafbf8; } /* ---------- tips list ---------- */ .gw-tips { padding-left: 18px; margin: 0; } .gw-tips li { margin: 6px 0; font-size: 14px; } /* ---------- mobile ---------- */ @media (max-width: 640px) { .gw-hero { padding: 18px 16px; gap: 12px; } .gw-hero__emoji { font-size: 44px; } .gw-hero__label { font-size: 22px; } .gw-hero__meta { width: 100%; justify-content: flex-end; } .gw-section { padding: 14px 16px; } .gw-why { padding: 12px 16px; } .gw-badges { padding: 12px 16px 0; } .gw-footer { padding: 12px 16px; } .gw-id__row { flex-direction: column; align-items: flex-start; gap: 2px; } .gw-id__label { min-width: 0; font-size: 12px; } .gw-pageheader h1 { font-size: 24px; } } /* Gradio chrome cleanups */ .gw-pageheader + * { margin-top: 8px; } /* ----- Phase 8: personalisation banner ----- */ .gw-personal-banner { margin: 12px 16px 0; padding: 12px 14px; background: linear-gradient(135deg, #f0f7ff 0%, #e6f0ff 100%); border: 1px solid #c7d8ee; border-radius: 10px; font-size: 13px; color: #243a5a; } .gw-personal-banner__head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; } .gw-personal-banner__title { font-weight: 600; } .gw-personal-banner__bucket { margin-left: auto; padding: 2px 8px; border-radius: 9999px; background: #ffffff; font-size: 11px; color: #5b6961; border: 1px solid #d6dee0; } .gw-personal-banner__list { margin: 0; padding-left: 18px; } .gw-personal-banner__list li { margin: 2px 0; } .gw-personal-banner code { background: #ffffff; padding: 1px 6px; border-radius: 4px; font-size: 12px; border: 1px solid #d6dee0; } /* ----- Phase 8: My Scans table ----- */ .gw-scans-wrap { overflow-x: auto; margin-top: 8px; } .gw-scans { width: 100%; border-collapse: collapse; font-size: 13px; } .gw-scans th, .gw-scans td { padding: 8px 10px; border-bottom: 1px solid #eaeef0; text-align: left; vertical-align: top; } .gw-scans th { background: #f5f7f7; font-weight: 600; font-size: 12px; color: #5b6961; text-transform: uppercase; letter-spacing: 0.04em; } .gw-scans__when { white-space: nowrap; color: #5b6961; font-family: ui-monospace, monospace; font-size: 12px; } .gw-scans__axes { white-space: nowrap; color: #5b6961; font-family: ui-monospace, monospace; font-size: 12px; } .gw-chip--good { background: #e7f5ec; color: #1f6b3a; } .gw-chip--warn { background: #fff5e0; color: #8a5a05; } .gw-chip--bad { background: #fde8e8; color: #8a1f1f; } /* ----- About / How it works tab ----- */ .gw-about-verdicts { list-style: none; padding: 0; margin: 8px 0; } .gw-about-verdicts li { padding: 10px 0; border-bottom: 1px solid #eaeef0; font-size: 14px; line-height: 1.5; } .gw-about-verdicts li:last-child { border-bottom: none; } .gw-about-verdicts .gw-chip { display: inline-block; margin-right: 8px; font-weight: 600; letter-spacing: 0.04em; } .gw-disclaimers { background: #fffbf2; border-left: 4px solid #d8a13b; padding-left: 16px; } .gw-disclaimers ol { padding-left: 20px; } .gw-disclaimers li { margin: 8px 0; line-height: 1.55; } /* ----- Phase 8c: My Scans aggregate summary ----- */ .gw-summary-tallies { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 10px; } .gw-summary-tally { text-align: center; padding: 12px 8px; border-radius: 10px; border: 1px solid transparent; display: flex; flex-direction: column; gap: 2px; } .gw-summary-tally--good { background: #e7f5ec; border-color: #b9dec7; color: #1f6b3a; } .gw-summary-tally--warn { background: #fff5e0; border-color: #e8d29a; color: #8a5a05; } .gw-summary-tally--bad { background: #fde8e8; border-color: #e6b5b5; color: #8a1f1f; } .gw-summary-tally__count { font-size: 28px; font-weight: 700; line-height: 1.1; } .gw-summary-tally__label { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; } .gw-summary-tally__pct { font-size: 11px; opacity: 0.7; } .gw-summary-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } .gw-summary-col h3 { margin: 0 0 4px; font-size: 14px; font-weight: 600; } .gw-section__subtitle { font-size: 14px; font-weight: 600; margin: 0 0 4px; color: #243a5a; } .gw-brand-list { list-style: none; padding: 0; margin: 8px 0 0; font-size: 13px; } .gw-brand-list li { padding: 6px 0; border-bottom: 1px dashed #eaeef0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; } .gw-brand-list li:last-child { border-bottom: none; } .gw-brand-name { font-weight: 600; flex: 1; min-width: 100px; } .gw-brand-mix { display: inline-flex; gap: 4px; } .gw-mix { display: inline-block; padding: 1px 6px; font-size: 11px; font-weight: 600; border-radius: 4px; font-family: ui-monospace, monospace; } .gw-mix--good { background: #e7f5ec; color: #1f6b3a; } .gw-mix--warn { background: #fff5e0; color: #8a5a05; } .gw-mix--bad { background: #fde8e8; color: #8a1f1f; } .gw-empty-table { padding: 24px; text-align: center; color: #5b6961; border: 1px dashed #d6dee0; border-radius: 10px; margin-top: 8px; } .gw-empty-table p { margin: 4px 0; } @media (max-width: 720px) { .gw-summary-cols { grid-template-columns: 1fr; } .gw-summary-tally__count { font-size: 22px; } } """