/* eBay Category Mapper - application styles */

:root {
    --sidebar: #16202e;
    --sidebar-2: #1e2a3b;
    --ink: #101828;
    --muted: #667085;
    --line: #e4e7ec;
    --bg: #f7f8fa;
    --card: #ffffff;
    --accent: #2563eb;
    --accent-soft: #eff4ff;
    --ok: #067647;
    --ok-soft: #ecfdf3;
    --warn: #b54708;
    --warn-soft: #fffaeb;
    --err: #b42318;
    --err-soft: #fef3f2;
    --radius: 10px;
    --mono: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;
    /* One family for the whole interface. Roboto first, then the closest thing
       each platform ships, so the page stays legible even if the webfont never
       arrives. */
    --sans: "Roboto", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
            "Helvetica Neue", Arial, "Noto Sans", sans-serif;
}

* { box-sizing: border-box; }

/* ---------------------------------------------------------------------------
   Typography.

   Roboto is requested in the layout. Everything falls back through --sans, so a
   slow or blocked webfont changes the look, never the layout or legibility.

   Form controls and headings do not inherit the document font by default in
   every browser, which is why they are listed explicitly - otherwise the
   interface quietly ends up with two typefaces.
   --------------------------------------------------------------------------- */
input, select, textarea, button, optgroup { font-family: inherit; }

h1, h2, h3, h4, h5, h6 {
    font-family: var(--sans);
    letter-spacing: -.015em;
}

html, body { margin: 0; padding: 0; }

body {
    background: var(--bg);
    color: var(--ink);
    font: 15px/1.55 var(--sans);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

code, pre, .mono { font-family: var(--mono); font-size: .86em; }

/* ---------- layout ---------- */

.shell { display: flex; min-height: 100vh; }

.sidebar {
    width: 236px;
    flex: 0 0 236px;
    background: var(--sidebar);
    color: #cbd5e1;
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
}

.brand {
    display: flex;
    align-items: center;
    gap: .7rem;
    padding: 1.1rem 1.1rem 1rem;
    border-bottom: 1px solid rgba(255,255,255,.08);
}
.brand-mark {
    width: 34px; height: 34px;
    display: grid; place-items: center;
    background: linear-gradient(135deg, #3b82f6, #8b5cf6);
    color: #fff; font-weight: 700; font-size: .82rem;
    border-radius: 9px; letter-spacing: -.02em;
}
.brand strong { display: block; color: #f1f5f9; font-size: .92rem; line-height: 1.2; }
.brand small { color: #7c8ba1; font-size: .72rem; }

.nav { padding: .8rem .6rem; display: flex; flex-direction: column; gap: 2px; flex: 1; }

.nav-link {
    display: flex; align-items: center; gap: .65rem;
    padding: .52rem .7rem;
    border-radius: 8px;
    color: #cbd5e1;
    font-size: .89rem;
    text-decoration: none;
}
.nav-link:hover { background: rgba(255,255,255,.06); color: #f1f5f9; text-decoration: none; }
.nav-link.is-active { background: var(--sidebar-2); color: #fff; box-shadow: inset 3px 0 0 #3b82f6; }
.nav-icon { width: 18px; text-align: center; opacity: .85; font-size: .95rem; }

.sidebar-foot { padding: .8rem .6rem 1.1rem; border-top: 1px solid rgba(255,255,255,.08); }

.mode {
    display: flex; align-items: center; gap: .45rem;
    margin: .8rem .7rem .3rem;
    font-size: .74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
}
.mode .dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.mode-demo { color: #fbbf24; }
.mode-live { color: #34d399; }
.mode-detail { margin: 0 .7rem; font-size: .76rem; color: #7c8ba1; }
.mode-detail a { color: #93c5fd; }

.main { flex: 1; min-width: 0; padding: 1.6rem 2rem 3rem; }

.foot {
    margin-top: 3rem; padding-top: 1rem;
    border-top: 1px solid var(--line);
    color: var(--muted); font-size: .78rem;
}

/* ---------- headers ---------- */

.page-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap; margin-bottom: 1.3rem;
}
.page-head h1 { margin: 0 0 .2rem; font-size: 1.4rem; letter-spacing: -.015em; }
.page-head p { margin: 0; color: var(--muted); font-size: .89rem; max-width: 68ch; }
.page-actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }

h2 { font-size: 1.05rem; margin: 0 0 .2rem; letter-spacing: -.01em; }
h3 { font-size: .93rem; margin: 0 0 .5rem; }
.section-sub { color: var(--muted); font-size: .84rem; margin: 0 0 .9rem; }

/* ---------- cards ---------- */

.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.15rem 1.25rem;
    margin-bottom: 1.1rem;
}
.card-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: .8rem; flex-wrap: wrap; margin-bottom: .85rem;
}
.card-head h2, .card-head h3 { margin: 0; }
.card.flush { padding: 0; overflow: hidden; }

.grid { display: grid; gap: 1.1rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

/* ---------- stats ---------- */

.stat { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: .95rem 1.05rem; }
.stat-label { color: var(--muted); font-size: .76rem; text-transform: uppercase; letter-spacing: .04em; font-weight: 700; }
.stat-value { font-size: 1.65rem; font-weight: 700; line-height: 1.2; margin: .25rem 0 0; letter-spacing: -.02em; }
.stat-note { color: var(--muted); font-size: .79rem; margin-top: .15rem; }
.stat.is-ok .stat-value { color: var(--ok); }
.stat.is-warn .stat-value { color: var(--warn); }
.stat.is-err .stat-value { color: var(--err); }

/* ---------- buttons ---------- */

.btn {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .46rem .85rem;
    border: 1px solid var(--line);
    background: #fff; color: var(--ink);
    border-radius: 8px; font-size: .86rem; font-weight: 500;
    cursor: pointer; text-decoration: none; line-height: 1.3;
    white-space: nowrap;
}
.btn:hover { background: #f9fafb; text-decoration: none; }
.btn:disabled, .btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: #1d4ed8; }
.btn-ok { background: var(--ok); border-color: var(--ok); color: #fff; }
.btn-ok:hover { background: #05603a; }
.btn-danger { background: #fff; border-color: #fda29b; color: var(--err); }
.btn-danger:hover { background: var(--err-soft); }
.btn-sm { padding: .3rem .6rem; font-size: .79rem; }
.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn-ghost:hover { background: #f2f4f7; }

.btn-row { display: flex; gap: .45rem; flex-wrap: wrap; align-items: center; }

/* ---------- forms ---------- */

label { display: block; font-size: .82rem; font-weight: 700; margin-bottom: .3rem; color: #344054; }
.hint { color: var(--muted); font-size: .78rem; margin-top: .3rem; line-height: 1.45; }

input[type=text], input[type=password], input[type=number], input[type=search], input[type=file], select, textarea {
    width: 100%; padding: .48rem .62rem;
    border: 1px solid #d0d5dd; border-radius: 8px;
    font: inherit; font-size: .88rem; background: #fff; color: var(--ink);
}
input[type=file] { padding: .38rem .5rem; }
input:focus, select:focus, textarea:focus { outline: 2px solid #bfdbfe; outline-offset: -1px; border-color: var(--accent); }
textarea { min-height: 90px; resize: vertical; }
input[type=checkbox] { width: auto; margin-right: .4rem; }

.field { margin-bottom: .95rem; }
.field-row { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.checkline { display: flex; align-items: center; font-weight: 500; font-size: .87rem; }
.checkline input { margin: 0 .5rem 0 0; }

fieldset { border: 0; padding: 0; margin: 0 0 1.3rem; }
legend {
    font-size: .74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    color: var(--muted); padding: 0 0 .55rem; border-bottom: 1px solid var(--line);
    width: 100%; margin-bottom: .9rem;
}

.inline-form { display: inline; }

/* ---------- tables ---------- */

.table-wrap { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; font-size: .86rem; }
th, td { text-align: left; padding: .58rem .7rem; border-bottom: 1px solid var(--line); vertical-align: top; }
th {
    font-size: .72rem; text-transform: uppercase; letter-spacing: .045em;
    color: var(--muted); font-weight: 700; background: #fafbfc; white-space: nowrap;
}
tbody tr:hover { background: #fafbfc; }
tbody tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td.tight { white-space: nowrap; }
td.wrap { max-width: 420px; }

.empty { padding: 2.2rem 1rem; text-align: center; color: var(--muted); }
.empty strong { display: block; color: var(--ink); margin-bottom: .3rem; }

/* ---------- badges ---------- */

.badge {
    display: inline-block; padding: .12rem .48rem;
    border-radius: 999px; font-size: .72rem; font-weight: 700;
    border: 1px solid transparent; white-space: nowrap;
}
.badge-gray  { background: #f2f4f7; color: #475467; border-color: #eaecf0; }
.badge-blue  { background: var(--accent-soft); color: #1d4ed8; border-color: #d1e0ff; }
.badge-green { background: var(--ok-soft); color: var(--ok); border-color: #abefc6; }
.badge-amber { background: var(--warn-soft); color: var(--warn); border-color: #fedf89; }
.badge-red   { background: var(--err-soft); color: var(--err); border-color: #fecdca; }
.badge-violet{ background: #f4f3ff; color: #5925dc; border-color: #d9d6fe; }

.score { font-variant-numeric: tabular-nums; font-weight: 700; }
.score-high { color: var(--ok); }
.score-mid { color: var(--warn); }
.score-low { color: var(--err); }

/* ---------- flashes ---------- */

.flashes { margin-bottom: 1.1rem; display: flex; flex-direction: column; gap: .55rem; }
.flash {
    display: flex; align-items: flex-start; gap: .8rem;
    padding: .72rem .9rem; border-radius: 9px; border: 1px solid; font-size: .87rem;
}
.flash-success { background: var(--ok-soft); border-color: #abefc6; color: #054f31; }
.flash-error   { background: var(--err-soft); border-color: #fecdca; color: #7a271a; }
.flash-warning { background: var(--warn-soft); border-color: #fedf89; color: #7a2e0e; }
.flash-info    { background: var(--accent-soft); border-color: #d1e0ff; color: #194185; }
.flash-body { flex: 1; }
.flash-text { font-weight: 500; }
.flash-hint { margin: .4rem 0 0; font-size: .82rem; opacity: .9; }
.flash-details { margin: .35rem 0 0; padding-left: 1.1rem; font-size: .8rem; }
.flash-close { background: none; border: 0; font-size: 1.2rem; line-height: 1; cursor: pointer; color: inherit; opacity: .55; padding: 0 .2rem; }
.flash-close:hover { opacity: 1; }

/* ---------- candidate list ---------- */

.candidates { display: flex; flex-direction: column; gap: .55rem; }

.candidate {
    border: 1px solid var(--line); border-radius: 9px;
    padding: .7rem .85rem; background: #fff;
}
.candidate.is-best { border-color: #a4c4ff; background: #fbfcff; }
.candidate-main { display: flex; align-items: baseline; justify-content: space-between; gap: .8rem; flex-wrap: wrap; }
.candidate-name { font-weight: 700; }
.candidate-path { color: var(--muted); font-size: .8rem; margin-top: .15rem; }
.candidate-reasons { margin: .45rem 0 0; padding-left: 1.05rem; color: var(--muted); font-size: .79rem; }
.candidate-reasons li { margin: .12rem 0; }
.candidate-actions { display: flex; gap: .4rem; align-items: center; margin-top: .55rem; flex-wrap: wrap; }

.evidence { font-size: .74rem; color: var(--muted); font-family: var(--mono); }

/* ---------- misc ---------- */

.kv { display: grid; grid-template-columns: minmax(120px, 190px) 1fr; gap: .3rem .9rem; font-size: .87rem; }
.kv dt { color: var(--muted); font-weight: 500; }
.kv dd { margin: 0; word-break: break-word; }

.meter { height: 6px; background: #eaecf0; border-radius: 999px; overflow: hidden; min-width: 80px; }
.meter span { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.meter.is-high span { background: var(--ok); }
.meter.is-mid span { background: #f79009; }
.meter.is-low span { background: #f04438; }

.pills { display: flex; gap: .35rem; flex-wrap: wrap; }
.pill {
    display: inline-block; padding: .16rem .5rem; border-radius: 6px;
    background: #f2f4f7; color: #475467; font-size: .75rem; font-family: var(--mono);
}

.issues { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .3rem; }
.issues li { padding: .4rem .6rem; border-radius: 7px; font-size: .82rem; border: 1px solid; }
.issues .is-error { background: var(--err-soft); border-color: #fecdca; color: #7a271a; }
.issues .is-warning { background: var(--warn-soft); border-color: #fedf89; color: #7a2e0e; }

/* ---------- chunked batch progress ---------- */

.progress-panel {
    margin-top: .8rem;
    padding: .75rem .85rem;
    border: 1px solid var(--line);
    border-radius: 9px;
    background: #fafbfc;
}
.progress-bar {
    height: 8px;
    background: #eaecf0;
    border-radius: 999px;
    overflow: hidden;
}
.progress-bar span {
    display: block;
    height: 100%;
    width: 0;
    background: linear-gradient(90deg, #2563eb, #7c3aed);
    border-radius: 999px;
    transition: width .25s ease;
}
.progress-text {
    margin: .5rem 0 0;
    font-size: .84rem;
    font-weight: 500;
    color: #344054;
}
.progress-log {
    margin: .5rem 0 0;
    max-height: 160px;
    overflow: auto;
    background: #0b1220;
    color: #cbd5e1;
    border-radius: 7px;
    padding: .55rem .7rem;
    font-family: var(--mono);
    font-size: .74rem;
    line-height: 1.5;
    white-space: pre-wrap;
}

/* ---------- preflight checklist ---------- */

.checklist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .4rem; }
.checklist li {
    display: flex; gap: .6rem; align-items: flex-start;
    padding: .55rem .7rem; border-radius: 8px; border: 1px solid var(--line);
    background: #fff; font-size: .86rem;
}
.checklist li.is-ok { background: var(--ok-soft); border-color: #abefc6; }
.checklist li.is-warn { background: var(--warn-soft); border-color: #fedf89; }
.checklist li.is-error { background: var(--err-soft); border-color: #fecdca; }
.checklist .mark { font-weight: 700; min-width: 1.1rem; }
.checklist .detail { color: var(--muted); font-size: .8rem; margin-top: .1rem; }

.scope-list { list-style: none; margin: .5rem 0 0; padding: 0; font-size: .78rem; }
.scope-list li { padding: .18rem 0; font-family: var(--mono); word-break: break-all; }

.oauth-url {
    display: block;
    background: #0b1220;
    color: #93c5fd;
    padding: .6rem .7rem;
    border-radius: 8px;
    font-family: var(--mono);
    font-size: .74rem;
    word-break: break-all;
    margin-top: .4rem;
}
.issues strong { font-family: var(--mono); font-size: .78rem; }

/* ---------- sidebar parent entry and children ---------- */

.nav-parent { font-weight: 700; }
.nav-badge {
    margin-left: auto;
    background: var(--accent);
    color: #fff;
    border-radius: 999px;
    padding: .05rem .45rem;
    font-size: .68rem;
    font-weight: 700;
}
.nav-children {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    margin: .1rem 0 .25rem .6rem;
    padding-left: .6rem;
    border-left: 2px solid var(--line);
}
.nav-child {
    font-size: .82rem;
    padding: .3rem .5rem;
    opacity: .85;
}
/* The parent .nav-link.is-active rule also matches this element and sets white
   text on a blue background with an inset bar. Neither suits a sub-item on the
   pale highlight, so both are overridden: without this the selected sub-item is
   white text on a near-white background and is unreadable. */
.nav-child.is-active {
    opacity: 1;
    font-weight: 700;
    background: var(--accent-soft);
    color: #1d4ed8;
    box-shadow: inset 2px 0 0 var(--accent);
}
.nav-child.is-active:hover { background: #e2ebff; color: #1d4ed8; }

.mode-banner {
    display: flex; align-items: center; gap: .6rem;
    padding: .6rem .85rem; border-radius: 9px; margin-bottom: 1.1rem;
    background: var(--warn-soft); border: 1px solid #fedf89; color: #7a2e0e; font-size: .85rem;
}
.mode-banner strong { font-weight: 700; }

.pagination { display: flex; gap: .3rem; align-items: center; margin-top: 1rem; flex-wrap: wrap; }
.pagination a, .pagination span {
    padding: .3rem .6rem; border: 1px solid var(--line); border-radius: 7px;
    font-size: .82rem; background: #fff; color: var(--ink);
}
.pagination .is-current { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700; }
.pagination .is-gap { border: 0; background: none; color: var(--muted); }

.tree-list { list-style: none; margin: 0; padding: 0; }
.tree-list li { border-bottom: 1px solid var(--line); }
.tree-list li:last-child { border-bottom: 0; }
.tree-list a { display: flex; align-items: center; justify-content: space-between; gap: .8rem; padding: .5rem .2rem; color: var(--ink); }
.tree-list a:hover { text-decoration: none; background: #fafbfc; }
.tree-list .nav-into { color: var(--muted); font-size: .8rem; }

.filters { display: flex; gap: .6rem; flex-wrap: wrap; align-items: flex-end; }
.filters .field { margin-bottom: 0; min-width: 150px; }

details.expander { border: 1px solid var(--line); border-radius: 9px; margin-bottom: .7rem; background: #fff; }
details.expander > summary { padding: .65rem .85rem; cursor: pointer; font-weight: 700; font-size: .87rem; }
details.expander > summary:hover { background: #fafbfc; }
details.expander > div { padding: 0 .85rem .85rem; }

pre.code {
    background: #0b1220; color: #cbd5e1; border-radius: 9px;
    padding: .85rem 1rem; overflow: auto; font-size: .78rem; line-height: 1.5; max-height: 380px;
}

.table-note { color: var(--muted); font-size: .8rem; margin: .5rem 0 0; }


/* ---------------------------------------------------------------------------
   Authentication screens.

   These pages are reached before a user exists, so they render outside the
   application shell and carry their own centred card layout.
   --------------------------------------------------------------------------- */
.auth-body{background:var(--bg,#f4f6f9);margin:0;min-height:100vh;
  font-family:var(--sans);color:#1f2430}
.auth-shell{max-width:440px;margin:0 auto;padding:48px 20px 64px}
.auth-brand{text-align:center;margin-bottom:22px}
.auth-brand a{font-weight:700;font-size:1.05rem;color:#2f5bea;text-decoration:none;letter-spacing:-.01em}
.auth-card{background:#fff;border:1px solid #e3e6ec;border-radius:12px;padding:26px}
.auth-card h1{font-size:1.15rem;margin:0 0 14px;letter-spacing:-.01em}
.auth-lede{color:#4b5563;line-height:1.55;margin:0 0 16px;font-size:.92rem}
.auth-aside{margin:14px 0 0;font-size:.87rem;color:#6b7280}
.auth-aside a{color:#2f5bea}
.auth-card .btn-block{width:100%;margin-top:6px}
.auth-card .field{margin-bottom:14px}
.auth-card .field:last-of-type{margin-bottom:16px}
.hint-inline{color:#9aa1ad;font-weight:400;font-size:.85em}
.field-error{color:#c0392b;font-size:.82rem;margin:.3rem 0 0}
.field-check{margin:4px 0 16px}
.check{display:flex;gap:.55rem;align-items:flex-start;font-size:.87rem;line-height:1.5;color:#374151}
.check input{margin-top:.22rem;flex:0 0 auto}
.password-wrap{position:relative;display:flex}
.password-wrap input{flex:1;padding-right:64px}
.password-toggle{position:absolute;right:6px;top:50%;transform:translateY(-50%);
  background:none;border:0;color:#2f5bea;font-size:.8rem;font-weight: 700;cursor:pointer;padding:4px 8px;border-radius:5px}
.password-toggle:hover{background:#eef2ff}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}
.signed-in{border-top:1px solid rgba(255,255,255,.09);margin-top:.7rem;padding-top:.7rem}
.signed-in-email{font-size:.78rem;opacity:.85;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.signed-in-role{font-size:.7rem;opacity:.6;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}

/* ---------------------------------------------------------------------------
   Helpers used by the account administration screen.
   --------------------------------------------------------------------------- */
.divider { border-top: 1px solid var(--line, #e3e6ec); margin: 1.1rem 0; }
.stack .field-row { margin-bottom: .6rem; }
tr.is-selected { background: #f4f7ff; }
[disabled] { opacity: .55; cursor: not-allowed; }

/* ---------------------------------------------------------------------------
   Authentication screens, refinement pass.

   These override the earlier block so the sign-in pages look right regardless of
   the application shell styles: a centred, comfortably sized card with inputs
   that cannot stretch beyond it.
   --------------------------------------------------------------------------- */
.auth-body {
    background: linear-gradient(180deg, #eef2f9 0%, #f7f9fc 320px, #f7f9fc 100%);
    min-height: 100vh;
}
.auth-shell {
    max-width: 460px;
    margin: 0 auto;
    padding: 56px 20px 72px;
}
.auth-brand { text-align: center; margin-bottom: 26px; }
.auth-brand a {
    font-weight: 700; font-size: 1.12rem; color: #24304a;
    text-decoration: none; letter-spacing: -.015em;
}
.auth-card {
    background: #fff;
    border: 1px solid #e2e6ee;
    border-radius: 14px;
    padding: 30px 30px 26px;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 10px 28px -14px rgba(16, 24, 40, .16);
}
.auth-card h1 {
    font-size: 1.24rem; margin: 0 0 6px; letter-spacing: -.02em; color: #111827;
}
.auth-lede { color: #55606f; line-height: 1.55; margin: 0 0 18px; font-size: .9rem; }
.auth-card .field { margin-bottom: 15px; }
.auth-card .field label {
    display: block; font-size: .82rem; font-weight: 700;
    color: #37414f; margin-bottom: .3rem;
}
.auth-card input[type=text],
.auth-card input[type=email],
.auth-card input[type=password] {
    width: 100%;
    padding: .62rem .75rem;
    font-size: .92rem;
    border: 1px solid #d3d9e3;
    border-radius: 9px;
    background: #fdfdff;
}
.auth-card input[type=text]:focus,
.auth-card input[type=email]:focus,
.auth-card input[type=password]:focus {
    outline: 0;
    border-color: var(--accent, #2f5bea);
    box-shadow: 0 0 0 3px rgba(47, 91, 234, .14);
    background: #fff;
}
.auth-card .btn-block { width: 100%; padding: .66rem 1rem; font-size: .93rem; margin-top: .35rem; }
.auth-card .hint { font-size: .79rem; color: #77808f; margin: .35rem 0 0; line-height: 1.5; }
.auth-card .field-error { color: #c0392b; font-size: .8rem; margin: .3rem 0 0; }
.auth-aside { margin: 15px 0 0; font-size: .86rem; color: #66707e; text-align: center; }
.auth-aside a { color: var(--accent, #2f5bea); font-weight: 500; }
.auth-card .flash { margin-bottom: 16px; font-size: .86rem; }
.password-wrap { position: relative; display: block; }
.password-wrap input { padding-right: 62px; }
.password-toggle {
    position: absolute; right: 7px; top: 50%; transform: translateY(-50%);
    background: none; border: 0; color: var(--accent, #2f5bea);
    font-size: .78rem; font-weight: 700; cursor: pointer;
    padding: 5px 9px; border-radius: 6px; line-height: 1;
}
.password-toggle:hover { background: #eef2ff; }
.password-toggle:focus-visible { outline: 2px solid var(--accent, #2f5bea); outline-offset: 1px; }

@media (max-width: 520px) {
    .auth-shell { padding: 28px 14px 48px; }
    .auth-card { padding: 22px 18px; border-radius: 12px; }
}

/* ---------------------------------------------------------------------------
   Banner with an inline action, used by the demo-mode notice.
   --------------------------------------------------------------------------- */
.banner-action {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap;
}
.banner-action form { flex: 0 0 auto; }
@media (max-width: 620px) {
    .banner-action { align-items: flex-start; }
    .banner-action form { width: 100%; }
    .banner-action .btn { width: 100%; }
}

/* ---------------------------------------------------------------------------
   Legal documents.
   --------------------------------------------------------------------------- */
.legal-shell { max-width: 760px; margin: 0 auto; padding: 40px 20px 72px; }
.legal-card {
    background: #fff; border: 1px solid #e2e6ee; border-radius: 14px;
    padding: 34px 34px 26px;
    box-shadow: 0 1px 2px rgba(16,24,40,.04), 0 10px 28px -14px rgba(16,24,40,.16);
}
.legal-head { border-bottom: 1px solid #eef1f6; padding-bottom: 14px; margin-bottom: 20px; }
.legal-head h1 { margin: 0; font-size: 1.4rem; letter-spacing: -.02em; }
.legal-body { line-height: 1.7; color: #26303e; font-size: .95rem; }
.legal-body h2 { font-size: 1.05rem; margin: 1.6rem 0 .5rem; }
.legal-body h3 { font-size: .95rem; margin: 1.3rem 0 .4rem; }
.legal-body p { margin: 0 0 .9rem; }
.legal-body ul, .legal-body ol { margin: 0 0 .9rem 1.2rem; padding: 0; }
.legal-body li { margin-bottom: .35rem; }
.legal-body a { color: var(--accent, #2f5bea); }
.legal-foot {
    margin-top: 26px; padding-top: 16px; border-top: 1px solid #eef1f6;
    font-size: .85rem; color: #66707e;
}
.legal-sep { margin: 0 .5rem; color: #cbd2dd; }
.auth-footer { text-align: center; color: #8b93a3; font-size: .78rem; margin-top: 18px; }
.brand-mark {
    display: inline-grid; place-items: center;
    width: 30px; height: 30px; border-radius: 8px;
    background: var(--accent, #2f5bea); color: #fff;
    font-size: .78rem; font-weight: 700; letter-spacing: -.02em; flex: 0 0 auto;
}
.auth-brand .brand-mark { margin-right: .5rem; vertical-align: -8px; }
.auth-brand .brand-logo { margin-right: .5rem; vertical-align: -9px; }

.brand-preview {
    display: flex; align-items: center; gap: .7rem;
    border: 1px dashed #d7dce5; border-radius: 10px;
    padding: .8rem .9rem; margin: .9rem 0 .4rem; background: #fafbfd;
}
.brand-preview .brand-mark { width: 36px; height: 36px; font-size: .9rem; }
textarea[name$="_body"] { font-family: var(--mono); font-size: .82rem; line-height: 1.6; }



/* ===========================================================================
   Application shell and the sidebar.

   Two independent widths drive everything:

     --rail   the resting, icon-only width. The content is offset by exactly
              this much, so the page is never hidden behind the rail.
     --open   the expanded width.

   Pinning shifts the content (the offset becomes --open). Hovering expands the
   sidebar over the content instead, so moving the mouse does not relayout the
   page a hundred times a second. That is the single reason the earlier version
   stuttered.

   The open state is one class on .shell, set by the script. There is no :hover
   rule for the sidebar itself: a hover rule cannot coexist with a pin, because
   the pointer is still inside the panel at the moment the pin is released.
   =========================================================================== */
:root {
    --rail: 68px;
    --open: 250px;
    --ease: cubic-bezier(.32, .72, 0, 1);
    --dur: 240ms;
    --nav-hover: rgba(255, 255, 255, .07);
}

.shell {
    display: block;
    min-height: 100vh;
    --offset: var(--rail);
}

/* Pinned: the content makes room for the full panel. */
.shell.is-pinned { --offset: var(--open); }

.sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    width: var(--rail);
    display: flex;
    flex-direction: column;
    background: var(--sidebar);
    color: #cbd5e1;
    z-index: 70;
    transition: width var(--dur) var(--ease);
    /* Wide enough for labels and flyouts to escape; nothing relies on clipping. */
    overflow: visible;
}

.shell.is-open .sidebar { width: var(--open); }

.page {
    margin-left: var(--offset);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    transition: margin-left var(--dur) var(--ease);
}

.main { flex: 1; min-width: 0; padding: 1.5rem 2rem 2.5rem; }

/* ---------- header ---------- */

.sidebar-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .85rem .8rem;
    border-bottom: 1px solid rgba(255,255,255,.08);
    flex: 0 0 auto;
}

.brand-link {
    display: flex;
    align-items: center;
    gap: .6rem;
    min-width: 0;
    color: inherit;
    text-decoration: none;
    flex: 1;
    overflow: hidden;
}
.brand-link:hover { text-decoration: none; }

.brand-mark {
    width: 34px; height: 34px;
    display: grid; place-items: center;
    background: var(--accent, #3b82f6);
    color: #fff; font-weight: 700; font-size: .78rem;
    border-radius: 9px; letter-spacing: -.02em;
    flex: 0 0 auto;
}
.brand-logo { width: 34px; height: 34px; border-radius: 9px; object-fit: cover; flex: 0 0 auto; }

.brand-text {
    display: flex; flex-direction: column; min-width: 0;
    white-space: nowrap;
}
.brand-text strong {
    display: block; color: #f1f5f9; font-size: .9rem; line-height: 1.25;
    overflow: hidden; text-overflow: ellipsis;
}
.brand-text small { color: #8494ab; font-size: .71rem; overflow: hidden; text-overflow: ellipsis; }

/* The pin. Also the expand control on a touch device, where hover does not
   exist, so it is never hidden. */
.pin-btn {
    flex: 0 0 auto;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    background: rgba(255,255,255,.07);
    color: #cbd5e1;
    border: 0; border-radius: 7px;
    cursor: pointer;
    font-size: .85rem; line-height: 1;
    transition: background .15s, color .15s;
}
.pin-btn:hover { background: rgba(255,255,255,.16); color: #fff; }
.pin-btn[aria-pressed="true"] { background: var(--accent, #3b82f6); color: #fff; }
.pin-btn:focus-visible { outline: 2px solid #93b4ff; outline-offset: 2px; }
.shell.is-open .pin-icon { transform: scaleX(-1); }
.pin-icon { display: block; transition: transform var(--dur) var(--ease); }

/* ---------- navigation ---------- */

.nav { flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; padding: .5rem .5rem 0; }
.nav-list { list-style: none; margin: 0; padding: 0; }
.nav-item { position: relative; }

.nav-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0;
    height: 40px;
    padding: 0;
    border-radius: 8px;
    color: #c2cddc;
    font-size: .875rem;
    text-decoration: none;
    white-space: nowrap;
    transition: background .14s, color .14s;
}
.nav-link:hover { background: var(--nav-hover); color: #f5f8fc; text-decoration: none; }
.nav-link:focus-visible { outline: 2px solid #93b4ff; outline-offset: -2px; }

.nav-icon {
    flex: 0 0 var(--rail-icon, 52px);
    width: var(--rail-icon, 52px);
    display: grid; place-items: center;
    font-size: 1rem;
    opacity: .9;
    line-height: 1;
}

/* Active state is carried by a bar and a tint, and remains legible collapsed. */
.nav-link.is-active {
    background: rgba(255,255,255,.1);
    color: #fff;
    font-weight: 700;
}
.nav-link.is-active::before {
    content: "";
    position: absolute;
    left: 0; top: 8px; bottom: 8px;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--accent, #3b82f6);
}
.nav-link.is-active .nav-icon { opacity: 1; color: var(--accent, #7aa2ff); }

/* The label is absolutely positioned so it never alters the rail width. In the
   rail it becomes the tooltip; expanded, it is the inline label. */
.nav-label {
    position: absolute;
    left: calc(var(--rail-icon, 52px) + 2px);
    top: 50%;
    transform: translateY(-50%);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity .12s linear;
}

.shell.is-open .nav-label { opacity: 1; transition-delay: .08s; }

/* Collapsed: the label appears as a tooltip chip on hover or keyboard focus. */
.shell:not(.is-open) .nav-item:hover > .nav-link .nav-label,
.shell:not(.is-open) .nav-item:hover > .nav-row .nav-link .nav-label,
.shell:not(.is-open) .nav-link:focus-visible .nav-label {
    opacity: 1;
    transition-delay: 0s;
    background: #111a2b;
    color: #eef3fb;
    padding: .3rem .55rem;
    border-radius: 6px;
    box-shadow: 0 6px 18px -6px rgba(0,0,0,.6);
    z-index: 90;
}

.nav-badge {
    position: absolute;
    left: 34px; top: 6px;
    min-width: 16px; height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: var(--accent, #3b82f6);
    color: #fff;
    font-size: .62rem; font-weight: 700;
    display: grid; place-items: center;
    opacity: 0;
    transition: opacity .12s;
}
.shell.is-open .nav-badge { opacity: 1; transition-delay: .08s; }

/* ---------- parent rows and submenus ---------- */

.nav-row { display: flex; align-items: center; position: relative; }
.nav-row .nav-link { flex: 1 1 auto; }

.nav-expand {
    position: absolute;
    right: 6px; top: 50%;
    transform: translateY(-50%);
    width: 24px; height: 24px;
    display: none;
    place-items: center;
    background: none; border: 0; border-radius: 6px;
    color: #9fb0c6; cursor: pointer;
    font-size: .8rem; line-height: 1;
}
.nav-expand:hover { background: rgba(255,255,255,.12); color: #fff; }
.nav-expand:focus-visible { outline: 2px solid #93b4ff; outline-offset: 1px; }
.shell.is-open .nav-expand { display: grid; }

.nav-caret { display: block; transition: transform .16s var(--ease); }
.nav-expand[aria-expanded="true"] .nav-caret { transform: rotate(90deg); }

.nav-sub { list-style: none; margin: 0; padding: 0; }

/* Expanded: the submenu unfolds inline beneath its parent. */
.shell.is-open .nav-sub {
    max-height: 0;
    overflow: hidden;
    margin-left: 26px;
    border-left: 1px solid rgba(255,255,255,.1);
    transition: max-height .18s var(--ease);
}
.shell.is-open .nav-sub.is-expanded { max-height: 320px; }
.shell.is-open .nav-sub-link { height: 34px; font-size: .82rem; }
.shell.is-open .nav-sub-link .nav-icon { flex-basis: 22px; width: 22px; }
.nav-dot::after {
    content: "";
    width: 5px; height: 5px; border-radius: 50%;
    background: currentColor; opacity: .55;
}

/* Collapsed: the submenu becomes a floating flyout beside the rail, so the
   child labels are never squeezed into 68px. */
.shell:not(.is-open) .nav-sub {
    position: absolute;
    left: calc(var(--rail) + 6px);
    top: -4px;
    min-width: 210px;
    padding: .35rem;
    background: #101a2b;
    border: 1px solid rgba(255,255,255,.1);
    border-radius: 10px;
    box-shadow: 0 18px 40px -14px rgba(0,0,0,.7);
    opacity: 0;
    visibility: hidden;
    transform: translateX(-6px);
    transition: opacity .14s, transform .14s, visibility .14s;
    z-index: 95;
}
.shell:not(.is-open) .nav-sub .nav-label { position: static; transform: none; opacity: 1; padding: 0; background: none; box-shadow: none; }
.shell:not(.is-open) .nav-sub .nav-link { padding-right: .6rem; }
.shell:not(.is-open) .nav-sub .nav-icon { flex-basis: 22px; width: 22px; }

.shell:not(.is-open) .nav-item.has-children:hover > .nav-sub,
.shell:not(.is-open) .nav-item.has-children:focus-within > .nav-sub,
.shell:not(.is-open) .nav-sub.is-open {
    opacity: 1;
    visibility: visible;
    transform: translateX(0);
}

/* ---------- footer ---------- */

.sidebar-foot {
    flex: 0 0 auto;
    padding: .5rem .5rem .9rem;
    border-top: 1px solid rgba(255,255,255,.08);
}

.signed-in {
    margin: .5rem .2rem 0;
    padding-top: .5rem;
    border-top: 1px solid rgba(255,255,255,.08);
    white-space: nowrap;
    opacity: 0;
    transition: opacity .12s;
}
.shell.is-open .signed-in { opacity: 1; transition-delay: .08s; }
.signed-in-email { font-size: .76rem; color: #a9b6c8; overflow: hidden; text-overflow: ellipsis; }
.signed-in-role { font-size: .66rem; color: #6f7f96; text-transform: uppercase; letter-spacing: .05em; margin-bottom: .45rem; }

.mode, .mode-detail {
    margin-left: .45rem;
    white-space: nowrap;
    opacity: 0;
    transition: opacity .12s;
}
.shell.is-open .mode, .shell.is-open .mode-detail { opacity: 1; transition-delay: .08s; }
.mode {
    display: flex; align-items: center; gap: .4rem;
    margin-top: .7rem;
    font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
}
.mode .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.mode-demo { color: #fbbf24; }
.mode-live { color: #34d399; }
.mode-detail { font-size: .72rem; color: #6f7f96; }

/* ---------- mobile drawer chrome ---------- */

.mobile-bar {
    display: none;
    align-items: center;
    gap: .65rem;
    padding: .6rem .8rem;
    background: var(--sidebar);
    color: #e6ecf5;
    position: sticky;
    top: 0;
    z-index: 50;
}
.drawer-btn {
    width: 38px; height: 38px;
    display: grid; place-items: center;
    background: rgba(255,255,255,.09);
    color: #e6ecf5;
    border: 0; border-radius: 8px;
    font-size: 1.05rem; line-height: 1;
    cursor: pointer;
}
.drawer-btn:hover { background: rgba(255,255,255,.18); }
.drawer-btn:focus-visible { outline: 2px solid #93b4ff; outline-offset: 2px; }
.mobile-brand {
    display: grid; place-items: center;
    width: 26px; height: 26px;
    border-radius: 7px;
    background: var(--accent, #3b82f6);
    color: #fff; font-size: .66rem; font-weight: 700;
}
.mobile-title {
    font-size: .9rem; font-weight: 700;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(6, 12, 22, .5);
    z-index: 65;
    opacity: 0;
    transition: opacity .2s;
}
.drawer-backdrop[hidden] { display: none; }
.shell.is-drawer .drawer-backdrop { opacity: 1; }

/* ===========================================================================
   Tablet and phone.
   =========================================================================== */
@media (max-width: 1023px) {
    /* No hover expansion below this width: a tablet reports a coarse pointer,
       so the pin becomes the expand control. */
    .shell { --offset: var(--rail); }
    .shell.is-pinned { --offset: var(--rail); }
    .shell.is-open { --offset: var(--rail); }
    .page { transition: none; }
}

@media (max-width: 720px) {
    /* The rail is replaced by a drawer, so the content uses the full width and a
       hamburger appears in a sticky top bar. */
    .shell { --offset: 0px; --rail: 0px; }
    .shell.is-pinned, .shell.is-open { --offset: 0px; }
    .page { margin-left: 0; }
    .mobile-bar { display: flex; }

    .sidebar {
        width: var(--open);
        transform: translateX(-100%);
        transition: transform var(--dur) var(--ease);
        box-shadow: none;
    }
    .shell.is-drawer .sidebar {
        transform: translateX(0);
        box-shadow: 0 0 40px rgba(0,0,0,.5);
    }
    /* Inside the drawer everything reads as expanded. */
    .sidebar .nav-label, .sidebar .brand-text, .sidebar .nav-badge,
    .sidebar .signed-in, .sidebar .mode, .sidebar .mode-detail { opacity: 1; }
    .sidebar .nav-icon { flex-basis: 44px; width: 44px; }
    .sidebar .nav-expand { display: grid; }
    .sidebar .nav-sub {
        position: static; opacity: 1; visibility: visible; transform: none;
        max-height: 0; overflow: hidden; min-width: 0;
        margin-left: 26px; padding: 0; background: none; border: 0; box-shadow: none;
        border-left: 1px solid rgba(255,255,255,.1);
    }
    .sidebar .nav-sub.is-expanded { max-height: 320px; }
    .sidebar .nav-sub .nav-label { opacity: 1; position: static; transform: none; }
    .pin-btn { display: none; }

    .main { padding: 1rem .85rem 2.2rem; }
    .page-head { flex-direction: column; align-items: flex-start; gap: .35rem; }
    .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    table { min-width: 520px; }
    .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr !important; }
    .field-row { grid-template-columns: 1fr !important; }
    .btn-row { flex-wrap: wrap; }
    .btn-row .btn { flex: 1 1 auto; justify-content: center; }
    .kv { grid-template-columns: 1fr; }
    .kv dt { margin-top: .5rem; }
    .card { padding: .9rem; border-radius: 10px; }
    h1, .page-head h1 { font-size: 1.25rem; }
    code, kbd, samp, .mono { overflow-wrap: anywhere; word-break: break-word; }
    img, svg, video { max-width: 100%; height: auto; }
    pre.code { max-width: 100%; }
}

@media (max-width: 420px) {
    .main { padding: .85rem .65rem 2rem; }
    .auth-shell { padding: 24px 12px 40px; }
}

/* Respect a reduced-motion preference: everything still works, it just snaps. */
@media (prefers-reduced-motion: reduce) {
    .sidebar, .page, .nav-sub, .nav-label, .nav-badge, .brand-text,
    .signed-in, .mode, .mode-detail, .pin-icon, .nav-caret, .drawer-backdrop {
        transition-duration: 0ms !important;
        transition-delay: 0ms !important;
    }
}

/* ---------------------------------------------------------------------------
   Navigation scrolling.

   The submenu flyout and the collapsed-mode tooltips are absolutely positioned
   children of a nav item. A scrolling ancestor would clip them, so the nav only
   becomes a scroll container on a short viewport - where there is not enough
   height for a flyout to be useful anyway.
   --------------------------------------------------------------------------- */
.nav {
    flex: 1 1 auto;
    min-height: 0;
    overflow: visible;
    padding: .5rem .5rem 0;
}
.sidebar-foot { flex: 0 0 auto; }

@media (max-height: 720px) {
    .nav { overflow-y: auto; overflow-x: hidden; }
    .shell:not(.is-open) .nav-sub { position: static; opacity: 1; visibility: visible; }
}

/* The page must not scroll behind an open mobile drawer. */
body.is-nav-locked { overflow: hidden; }


/* The family only resolves once a face is registered, so the stack keeps the
   platform fonts behind it for the moment before the file loads. */

/* ---------------------------------------------------------------------------
   Item specific editor.

   Each row uses <details> so the Edit toggle works with no script at all: the
   native element opens and closes it, and the form inside posts one aspect.
   --------------------------------------------------------------------------- */
.aspect-table td { vertical-align: top; }
.aspect-edit { display: inline-block; }
.aspect-edit > summary {
    list-style: none;
    cursor: pointer;
    display: inline-block;
    padding: .3rem .6rem;
    border: 1px solid #d0d5dd;
    border-radius: 7px;
    background: #fff;
    font-size: .78rem;
    font-weight: 700;
    color: #37414f;
}
.aspect-edit > summary::-webkit-details-marker { display: none; }
.aspect-edit > summary:hover { background: #f4f6fa; border-color: #b9c2d0; }
.aspect-edit > summary:focus-visible { outline: 2px solid var(--accent, #2f5bea); outline-offset: 2px; }
.aspect-edit[open] > summary { background: var(--accent, #2f5bea); border-color: transparent; color: #fff; }
.aspect-form { margin-top: .45rem; min-width: 220px; }
.aspect-form input[type=text],
.aspect-form select { width: 100%; }
@media (max-width: 720px) {
    .aspect-form { min-width: 0; }
}

/* ---------------------------------------------------------------------------
   Roboto, self-hosted.

   Served from this installation rather than a third-party CDN, so no request
   leaves a visitor's browser for a font service. That keeps the privacy notice
   accurate and removes a dependency that can be slow or blocked.

   The full family is registered, so every weight and style the interface asks
   for is the real cut rather than one the browser synthesises. Only the faces a
   page actually uses are downloaded - a normal screen fetches Regular and
   Medium, and Bold only where something is emphasised.

   Files live directly in /assets because the asset server serves a single path
   segment; a fonts/ subdirectory would not resolve through the front controller.

   font-display:swap paints text immediately in the fallback and swaps when the
   file arrives, so a slow connection never shows blank text.
   --------------------------------------------------------------------------- */
@font-face {
    font-family: "Roboto";
    font-style: normal;
    font-weight: 100;
    font-display: swap;
    src: url("Roboto-Thin.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: italic;
    font-weight: 100;
    font-display: swap;
    src: url("Roboto-ThinItalic.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: normal;
    font-weight: 300;
    font-display: swap;
    src: url("Roboto-Light.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: italic;
    font-weight: 300;
    font-display: swap;
    src: url("Roboto-LightItalic.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("Roboto-Regular.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: url("Roboto-RegularItalic.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("Roboto-Medium.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: italic;
    font-weight: 500;
    font-display: swap;
    src: url("Roboto-MediumItalic.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("Roboto-Bold.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: italic;
    font-weight: 700;
    font-display: swap;
    src: url("Roboto-BoldItalic.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: normal;
    font-weight: 900;
    font-display: swap;
    src: url("Roboto-Black.woff2") format("woff2");
}
@font-face {
    font-family: "Roboto";
    font-style: italic;
    font-weight: 900;
    font-display: swap;
    src: url("Roboto-BlackItalic.woff2") format("woff2");
}



/* Request/response detail on the uploads screen. Long JSON, only relevant when
   a listing has failed, so it stays collapsed and scrolls rather than pushing
   the table apart. */
.payload-detail { margin: .3rem 0; }
.payload-detail > summary {
    cursor: pointer;
    font-size: .8rem;
    font-weight: 700;
    color: #37414f;
}
.payload {
    max-height: 260px;
    overflow: auto;
    background: #f7f8fa;
    border: 1px solid #e4e7ec;
    border-radius: 8px;
    padding: .6rem .7rem;
    font-size: .74rem;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
    margin: 0;
}
