/* The dashboard in the PWA's Material 3 colours and type (src/styles.css), light and dark. */ @font-face { font-family: "Roboto Flex"; src: url("/fonts/RobotoFlex-Variable.ttf") format("truetype"); font-weight: 100 1000; font-display: swap; } :root { color-scheme: light dark; --primary: #6750a4; --on-primary: #fff; --primary-container: #eaddff; --on-primary-container: #21005d; --secondary-container: #e8def8; --on-secondary-container: #1d192b; --surface: #fef7ff; --on-surface: #1d1b20; --on-surface-variant: #49454f; --container-lowest: #fff; --card: #fff; --container-low: #f7f2fa; --container: #f3edf7; --container-high: #ece6f0; --outline-variant: #cac4d0; --error: #b3261e; --error-container: #f9dedc; --on-error-container: #410e0b; --ok: #2e6b30; --ok-container: #c8efb8; --warn: #8a5100; --warn-container: #ffddb8; --font: "Roboto Flex", Roboto, system-ui, sans-serif; } @media (prefers-color-scheme: dark) { :root { --primary: #d0bcff; --on-primary: #381e72; --primary-container: #4f378b; --on-primary-container: #eaddff; --secondary-container: #4a4458; --on-secondary-container: #e8def8; --surface: #141218; --on-surface: #e6e0e9; --on-surface-variant: #cac4d0; --container-lowest: #0f0d13; /* Cards lift off the dark page as in the PWA: a container tone, not the darkest one. */ --card: #211f26; --container-low: #2b2930; --container: #211f26; --container-high: #2b2930; --outline-variant: #49454f; --error: #f2b8b5; --error-container: #8c1d18; --on-error-container: #f9dedc; --ok: #9fd79a; --ok-container: #1f4d24; --warn: #ffb95c; --warn-container: #693c00; } } * { box-sizing: border-box; } body { margin: 0; background: var(--surface); color: var(--on-surface); font: 400 15px/1.45 var(--font); -webkit-font-smoothing: antialiased; } h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: 0; } h1 { font-size: 1.6rem; } h2 { font-size: 1.15rem; } h3 { font-size: 0.95rem; margin-bottom: 8px; color: var(--on-surface-variant); } .muted { color: var(--on-surface-variant); } .small { font-size: 0.8rem; } .top { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; max-width: 1280px; margin: 0 auto; padding: 24px 16px 8px; } .sub { margin: 2px 0 0; color: var(--on-surface-variant); } .refresh { display: flex; align-items: center; gap: 12px; } button.tonal { border: 0; border-radius: 9999px; padding: 10px 20px; background: var(--secondary-container); color: var(--on-secondary-container); font: 600 0.875rem var(--font); cursor: pointer; } button.tonal:hover { filter: brightness(0.96); } button:focus-visible, input:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; } main { max-width: 1280px; margin: 0 auto; padding: 8px 16px 48px; display: grid; gap: 16px; } .banner { margin: 0; padding: 12px 16px; border-radius: 16px; } .banner.bad { background: var(--error-container); color: var(--on-error-container); } .warnings { margin: 0; padding: 12px 16px 12px 36px; border-radius: 16px; background: var(--warn-container); } .tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; } .tile { background: var(--card); border-radius: 20px; padding: 16px 18px; display: grid; gap: 4px; align-content: start; } .tile .label { font-size: 0.8rem; color: var(--on-surface-variant); display: flex; align-items: center; gap: 8px; } .tile .value { font-size: 1.25rem; font-weight: 600; } .tile .detail { font-size: 0.85rem; color: var(--on-surface-variant); } .dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; background: var(--outline-variant); } .dot.ok { background: var(--ok); } .dot.warn { background: var(--warn); } .dot.bad { background: var(--error); } .card { background: var(--card); border-radius: 28px; padding: 20px; min-width: 0; } .card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 14px; } .kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; margin-bottom: 16px; } .kpi { background: var(--container-low); border-radius: 16px; padding: 10px 14px; } .kpi b { display: block; font-size: 1.35rem; font-weight: 600; font-variant-numeric: tabular-nums; } .kpi span { font-size: 0.8rem; color: var(--on-surface-variant); } .kpi.warn { background: var(--warn-container); } .kpi.bad { background: var(--error-container); color: var(--on-error-container); } .chart { margin: 0 0 16px; } .chart svg { width: 100%; height: 140px; display: block; background: var(--container-low); border-radius: 12px; } .bar-fresh { fill: var(--primary); } .bar-cached { fill: var(--primary-container); } .bar-failed { fill: var(--error); } .legend { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 8px; font-size: 0.8rem; color: var(--on-surface-variant); align-items: center; } .legend .axis { margin-left: auto; display: flex; gap: 24px; } .swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; } .swatch.fresh { background: var(--primary); } .swatch.cached { background: var(--primary-container); } .swatch.failed { background: var(--error); } .split { display: grid; grid-template-columns: 3fr 2fr; gap: 24px; } table { width: 100%; border-collapse: collapse; font-size: 0.875rem; } th { text-align: left; font-weight: 500; color: var(--on-surface-variant); padding: 6px 8px; border-bottom: 1px solid var(--outline-variant); } td { padding: 7px 8px; border-bottom: 1px solid var(--container-high); overflow-wrap: anywhere; } .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; } .columns { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 16px; align-items: start; } .events { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; max-height: 720px; overflow: auto; } .events li { display: grid; grid-template-columns: auto 1fr; gap: 2px 12px; padding: 10px 4px; border-bottom: 1px solid var(--container-high); } .events .dot { margin-top: 6px; grid-row: span 3; } .events .when { font-size: 0.8rem; color: var(--on-surface-variant); } .events .title { font-weight: 500; overflow-wrap: anywhere; } .events .text { font-size: 0.85rem; color: var(--on-surface-variant); overflow-wrap: anywhere; } .filters { display: grid; gap: 10px; margin-bottom: 12px; } input[type="search"] { width: 100%; border: 1px solid var(--outline-variant); border-radius: 12px; padding: 10px 14px; background: var(--container-low); color: var(--on-surface); font: 400 0.95rem var(--font); } .chips { display: flex; flex-wrap: wrap; gap: 6px; } .chip { border: 1px solid var(--outline-variant); border-radius: 8px; padding: 6px 12px; background: transparent; color: var(--on-surface); font: 500 0.8rem var(--font); cursor: pointer; } .chip[aria-pressed="true"] { background: var(--secondary-container); color: var(--on-secondary-container); border-color: transparent; } .chip .n { margin-left: 6px; color: var(--on-surface-variant); font-variant-numeric: tabular-nums; } .doc { border-top: 1px solid var(--container-high); padding: 14px 0 6px; } .doc-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 6px; } .doc-head b { overflow-wrap: anywhere; } .doc-head a { color: var(--primary); font-size: 0.85rem; white-space: nowrap; } .problem { padding: 10px 0; } .problem + .problem { border-top: 1px dashed var(--container-high); } .problem .where { font-size: 0.8rem; color: var(--on-surface-variant); } .problem q { display: block; margin-top: 4px; padding: 6px 10px; border-radius: 8px; background: var(--container-low); font-size: 0.85rem; quotes: "«" "»"; overflow-wrap: anywhere; white-space: pre-wrap; } .failed-doc { padding: 10px 14px; border-radius: 12px; background: var(--error-container); color: var(--on-error-container); margin-bottom: 8px; } .empty { padding: 24px 0; text-align: center; color: var(--on-surface-variant); } @media (max-width: 900px) { .columns, .split { grid-template-columns: 1fr; } } @media (max-width: 560px) { .legend .axis { display: none; } }