/* The VARIABLE range, not four static cuts. This panel's weights were chosen
   against Inter's variable font and it asks for eight of them - 400, 450, 500,
   550, 600, 640, 650, 700. Loaded as static instances, Manrope had four, and
   measured on 2026-09-21 a 550 rendered pixel-for-pixel as a 600: every
   sidebar label, badge and button came out heavier and wider than it was
   designed, which is what "spacing and alignment look wrong" actually was. */
@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap');

/*
 * Facebook Client Finder admin panel.
 *
 * The design language was measured off the Shopify admin on 2026-09-03 and is
 * recorded in docs/mockup/DESIGN_LANGUAGE.md; the prototype in
 * docs/mockup/panel-prototype.html is the reference for every page. Three
 * things carry the feel: cards have no border and sit on elevation, sidebar
 * headers are ordinary dark text, and badges are 8px rectangles on a pastel
 * ground with dark same-hue text.
 *
 * Every colour is a variable in this one block so the operator's brand
 * replaces them in a single place. It did, on 2026-09-21: the ha. brand
 * (Brand Guide HA-BG-001 v01.0, and halilatabey.com). The Shopify structure is
 * untouched - the brand supplies the type, four colours and the mark.
 *
 * This block is the twin of the one in docs/mockup/panel-prototype.html and
 * the two are kept identical on purpose.
 */

:root {
    /* Paper carries the design. Ink builds structure. Lime is a signal. */
    --ink: #252525; --paper: #ffffff; --lime: #eafc48; --soft: #f4f4f2;

    --topbar: var(--ink); --topbar-text: #e8e8e6; --topbar-sub: #9e9e9c;
    --sidebar: #ebebe9;
    /* The selected row: a step darker than the hover, which paints #e2e2df over the
       #ebebe9 bar (measured 2026-09-21). Operator: "mouse u sol barda butonun
       uzerine getirdigimizde olan griligin cok az koyusu." Two other values
       were tried and refused first - lime, too loud; #3d3d3b, too dark - and
       #fafafa, the near-white the Shopify admin actually uses, which was
       measured off it on 2026-09-03 and read as no mark at all here. */
    --sidebar-active: #dcdcd8; --sidebar-active-text: var(--text);
    --app: var(--soft); --card: var(--paper); --card-2: #fafaf8;
    --text: var(--ink); --text-sub: #5f5f5d; --text-mute: #8a8a86;
    --border: #e0e0dd; --border-strong: #c9c9c5;

    /* THE ONE SIGNAL. Lime is a ground, never a line and never a letter:
       measured 2026-09-21, lime on paper is 1.14:1 - invisible - and ink on
       lime is 13.5:1, which clears AAA. White on lime is forbidden by the
       brand guide, and the measurement is why. */
    --signal: var(--lime); --signal-ink: var(--ink); --signal-edge: #dcef3f;

    /* A link, a focus ring, a clickable cell need contrast, so they are ink
       and carry an underline, the way halilatabey.com writes them. The blue
       that used to be here was 6.6:1 on paper; ink is 15.5:1. */
    --accent: var(--ink); --accent-soft: #edede9;
/* The three colours that carry meaning, and the grey that carries none.
       These are DATA - a listing is Live, under review or Closed - so they stay
       colours, and they are the operator's own instruction of 2026-09-21: their
       tones should suit the branding. Derived rather than picked, and measured:

         - Green sits on the lime's side of green (hue 112, not the blue-green
           157 that was here), so it belongs to a yellow-green brand.
         - Amber is pushed away from lime toward orange, and red away from amber,
           because the pair a person most needs to tell apart is a warning badge
           beside a failure badge.
         - The grey is warm (hue 60 at 6%), to match the brand's own neutrals.

       Measured 2026-09-21. Every dark-on-pale pair clears AA - 6.33, 5.37, 5.60
       and 5.06 - and the three grounds are clearly distinct by eye, CIE76 dE of
       20.3, 25.6 and 25.4 against a threshold of 10. The amber ground is dE 57.9
       from the brand lime, so a warning never reads as the mark. */
    --ok: #255f1c; --ok-soft: #d4f1d0;
    --warn: #7c5804; --warn-soft: #fce9b6;
    --bad: #af1d21; --bad-soft: #fae1e0;
    --idle: #646459; --idle-soft: #ecece9;
    /* Card elevation: no border, a stack of very soft shadows closed by a 1px ring. */
    --shadow: 0 5px 5px -2.5px rgba(0, 0, 0, .03), 0 3px 3px -1.5px rgba(0, 0, 0, .02),
              0 2px 2px -1px rgba(0, 0, 0, .02), 0 1px 1px -.5px rgba(0, 0, 0, .03),
              0 .5px .5px 0 rgba(0, 0, 0, .04), 0 0 0 1px rgba(0, 0, 0, .06);
    --radius: 12px;
    --sidebar-w: 240px; --topbar-h: 56px;
    /* Motion: one easing, two durations. */
    --ease: cubic-bezier(.2, .7, .2, 1); --fast: .12s; --med: .18s;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
html, body { height: 100%; }
body {
    margin: 0;
    background: var(--app);
    color: var(--text);
    font: 13px/1.45 Manrope, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    font-variant-numeric: tabular-nums;
    -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }


/* ---------------------------------------------------------------------------
   ONE FACE. Manrope, everywhere - headings, paragraphs, tables, buttons,
   numbers (operator, 2026-09-21: "tamam hepsi icin manrope yap. Sadece manrope
   kullan. tum tasarimlarda"). Roboto Mono was used for headings in capitals for
   part of that day and for machine text before it; it is now neither loaded nor
   asked for anywhere.

   What the monospaced face was actually doing is done by Manrope anyway: its
   job was columns of figures lining up, and the body sets
   font-variant-numeric: tabular-nums, so every digit in this panel is
   fixed-width whatever the face. The classes that used to switch face - .mono,
   .masked, the textareas, the Telegram preview - keep their other work (size,
   tracking, colour, ground) and simply inherit.
   --------------------------------------------------------------------------- */

/* ---------- top bar ---------- */
.topbar {
    position: fixed; inset: 0 0 auto 0; height: var(--topbar-h); background: var(--topbar);
    display: flex; align-items: center; z-index: 60; box-shadow: inset 0 -1px 0 #000;
}
.brand { width: var(--sidebar-w); flex: 0 0 var(--sidebar-w); display: flex; align-items: center; padding: 0 16px; height: 100%; }
/* ONE HORIZONTAL LINE THROUGH BOTH (operator, 2026-09-21): a line drawn
   through the middle of the mark and a line drawn through the middle of the
   word are the same line. align-items: center puts the two BOXES on it.
   The letters then sit a shade above that line, because "Client Finder" has no
   descender and its glyphs ride high in their own box - measured at 1.09px on
   the sign-in screen and 0.34px in this bar. So the mark is lifted by 1px and
   set a size smaller, which is what the operator asked for when they saw it:
   "logoyu biraz kucult ve sonra biraz yukari kaydir".

   THE LIFT IS THE LETTERS' OWN OFFSET, measured, and not one number for both:
   1px on the sign-in screen where the word is 15px, half of one here where it
   is 13.5. A flat 1px was tried in both and overshot this bar by 0.66px. After:
   0.09px apart there, 0.16px here - a tenth of a pixel, either way. */
.brand .lockup { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.brand .logo { height: 15px; aspect-ratio: 250/160; display: block; flex: 0 0 auto; background: var(--lime); transform: translateY(-.5px);
    -webkit-mask: url(ha-mark.png) center/contain no-repeat; mask: url(ha-mark.png) center/contain no-repeat; }
.brand .name { color: #f2f2f2; font-weight: 600; font-size: 13.5px; letter-spacing: -.01em; white-space: nowrap; }
.topbar-right { display: flex; align-items: center; gap: 6px; padding-right: 12px; margin-left: auto; }
/* Until Adım 2 wires authentication the bar says so, on every page, in the
   place the profile menu will take. Hiding the gap would be the worse choice. */
.sysbadge {
    display: flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: 999px;
    background: #2b2b2b; border: 1px solid #3d3d3d; color: #dcdcdc; font-size: 12px; white-space: nowrap;
}
.sysbadge .dot { width: 7px; height: 7px; border-radius: 50%; background: #ffd166; }

/* ---------- sidebar ---------- */
.sidebar {
    position: fixed; top: var(--topbar-h); bottom: 0; left: 0; width: var(--sidebar-w); background: var(--sidebar);
    border-right: 1px solid var(--border); display: flex; flex-direction: column; z-index: 50;
}
.nav { flex: 1; overflow-y: auto; padding: 8px 12px 4px; }
.sect { padding: 16px 8px 5px; font-size: 13px; font-weight: 600; color: var(--text); letter-spacing: 0; }
.nav a {
    display: flex; align-items: center; gap: 8px; height: 28px; padding: 0 4px 0 8px; border-radius: 8px;
    font-size: 13px; font-weight: 550; color: var(--text); margin-bottom: 1px;
    transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
/* No hover mark in this bar, by the operator's decision of 2026-09-21:
   "Mouse uzerine gittigindeki grilik olusmasin ve tikladigim yerde grilik
   olsun." One grey means one thing - where you are - and a row that greys
   under the pointer was saying the same thing about a row you are not on.
   The pointer still turns, so the row is still visibly a link. */
/* .nav a:hover paints nothing on purpose. */
/* Lime is the mark and nothing else on this bar. The active row was lime
   for part of 2026-09-21 and the operator refused it: "Sol barda Feed sync
   in acik sari kalmasi kotu gozukuyor. Onu koyu gri yap. Yine diger
   butonlarda da acik sari kullanma." A pale yellow block the size of a
   sidebar row is a lot of signal for "you are here"; a dark grey one says
   the same thing and stops shouting. */
.nav a.active { background: var(--sidebar-active); color: var(--sidebar-active-text); font-weight: 600; }
.nav a .ic { width: 16px; height: 16px; flex: 0 0 16px; display: grid; place-items: center; color: #4a4a4a; }
.nav a .ic svg { display: block; }
.nav a.active .ic { color: var(--sidebar-active-text); }
.nav a .lbl { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav a .lockic { font-size: 10px; opacity: .5; }
.badge {
    background: #e3e3e3; color: var(--text); border-radius: 8px; font-size: 12px; font-weight: 550;
    padding: 1px 7px; min-width: 20px; text-align: center; line-height: 18px;
}
.badge.alert { background: #ffd6d6; color: var(--bad); }
.badge.warn { background: #ffea8a; color: #4f3500; }
.navfoot { padding: 8px 12px 12px; border-top: 1px solid var(--border); font-size: 11.5px; color: var(--text-mute); }

/* ---------- content ---------- */
.main { margin: var(--topbar-h) 0 0 var(--sidebar-w); padding: 22px 26px 60px; max-width: 1320px; }
.pagehead { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 16px; flex-wrap: wrap; }
.pagehead h1, .main > h1 { margin: 0; font-size: 20px; font-weight: 600; letter-spacing: -.1666px; line-height: 24px; }
.main > h1 { margin-bottom: 16px; }
.pagehead .sub { color: var(--text-sub); font-size: 13px; margin-top: 4px; }
.pagehead .spacer { flex: 1; }
.main h2 { font-size: 13px; font-weight: 600; margin: 20px 0 8px; }

/* ---------- buttons ---------- */
/* 28px, 8px radius, 12px/550. Secondary is a filled grey chip with no border;
   primary is near-black with a dark inner top edge. Bare <button> elements
   take the secondary look so the Phase 2 pages need no markup change. */
button, .btn {
    height: 28px; padding: 0 12px; border-radius: 8px; border: 0; background: #e3e3e3; color: var(--text);
    cursor: pointer; font-size: 12px; font-weight: 550; display: inline-flex; align-items: center; gap: 6px;
    line-height: 1; text-decoration: none; white-space: nowrap;
    transition: background var(--fast) var(--ease), color var(--fast) var(--ease), transform .08s var(--ease);
}
button:hover, .btn:hover { background: #dadada; }
button:active, .btn:active { background: #d0d0d0; transform: translateY(.5px); }
/* The one action a page has: ink, the way it was measured, not lime. */
button.primary, button.pri, .btn.pri { background: var(--ink); color: var(--paper); font-weight: 600; box-shadow: inset 0 -1px 0 1px rgba(0, 0, 0, .8); }
button.primary:hover, button.pri:hover, .btn.pri:hover { background: #111; }
button.danger, .btn.danger { background: var(--bad-soft); color: var(--bad); }
button.danger:hover, .btn.danger:hover { background: #ffd0cb; }
button:disabled, .btn:disabled { opacity: .4; cursor: not-allowed; transform: none; }
button.sm, .btn.sm { height: 24px; padding: 0 9px; }

/* ---------- cards ---------- */
.card { background: var(--card); border: 0; border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 16px; overflow: hidden; }
.card > .hd { padding: 14px 16px 10px; display: flex; align-items: center; gap: 10px; }
.card > .hd h2 { margin: 0; font-size: 13px; font-weight: 600; line-height: 16px; }
.card > .hd .spacer { flex: 1; }
.card > .bd { padding: 16px; }
.card > .bd.tight { padding: 0; }
.hint { background: var(--card-2); border-top: 1px solid var(--border); padding: 10px 16px; font-size: 12px; color: var(--text-sub); }
.grid { display: grid; gap: 16px; margin-bottom: 16px; }
.grid > .card { margin-bottom: 0; }
.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .g3, .g2 { grid-template-columns: minmax(0, 1fr); } }

/* metric strip */
.metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 16px; }
/* Label, value, detail, top to bottom, as the prototype draws a metric (.metric there is a plain block).
   Until 2026-09-16 this rule shared a reversed flex column with the first build's stat tiles, which put
   the detail above the value and the label at the foot of every metric card on 13 pages. */
.metric { background: var(--card); border: 0; border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow); margin: 0; display: block; }
.metric .k { font-size: 13px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 6px; }
.metric .v { font-size: 20px; font-weight: 600; letter-spacing: -.1666px; margin-top: 5px; line-height: 24px; font-variant-numeric: tabular-nums; }
.metric .d { font-size: 12px; color: var(--text-sub); margin-top: 4px; }
.metric.bad .v { color: var(--bad); } .metric.warn .v { color: var(--warn); } .metric.ok .v { color: var(--ok); }
@media (max-width: 1100px) { .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---------- filter bar ---------- */
.filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.main > .filters { background: var(--card); border: 0; border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 16px; }
.filters label { display: inline-flex; align-items: center; gap: 6px; color: var(--text-sub); font-size: 12px; }
.chip, .filters select, .filters input {
    height: 28px; padding: 0 10px; border-radius: 8px; border: 0; background: #e3e3e3;
    font-size: 12px; font-weight: 550; color: var(--text); cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
    transition: background var(--fast) var(--ease);
}
.filters input[type="search"], .filters input[type="text"] { min-width: 180px; cursor: text; font-weight: 450; }
.filters input[type="checkbox"] { height: auto; padding: 0; background: none; }
.chip:hover, .filters select:hover { background: #dadada; }
.chip.on { background: #303030; color: #fff; box-shadow: inset 0 -1px 0 1px rgba(0, 0, 0, .8); }
.chip .n { opacity: .65; font-size: 11px; }

/* ---------- tables ---------- */
table { width: 100%; border-collapse: collapse; }
th {
    text-align: left; font-size: 12px; font-weight: 550; color: var(--text-sub); padding: 0 12px; height: 36px;
    border-bottom: 1px solid var(--border); white-space: nowrap; position: sticky; top: 0; background: var(--card);
}
td { padding: 0 12px; height: 52px; border-bottom: 1px solid #f0f0f0; font-size: 13px; vertical-align: middle; white-space: nowrap; }
td.wrap { white-space: normal; }
tbody tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
/* .num is for figures; .right is for a cell whose content is simply on the
   right, such as the one action at the end of a row. */
td.right, th.right { text-align: right; }
.mono { font-size: 12px; }
.sub { color: var(--text-sub); font-size: 12px; }
.masked { letter-spacing: .08em; color: var(--text-sub); }
td.reason { max-width: 28rem; white-space: normal; color: var(--text-sub); }
.rowacts { display: flex; gap: 6px; justify-content: flex-end; }
/* Tables scroll inside their own container; the page body never scrolls sideways. */
.table-scroll { overflow-x: auto; max-width: 100%; padding-bottom: 2px; }
.main > .table-scroll { background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 16px; }
.table-scroll table { min-width: 100%; }

/* ---------- status pills ---------- */
.pill { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 550; padding: 2px 8px; border-radius: 8px; white-space: nowrap; line-height: 16px; }
.pill.ok { background: var(--ok-soft); color: var(--ok); }
.pill.warn { background: #ffea8a; color: #4f3500; }
.pill.bad { background: #ffd6d6; color: var(--bad); }
.pill.idle { background: #e3e3e3; color: #4a4a4a; }
.pill.info { background: #d1e3ff; color: #00306e; }

/* ---------- banners and callouts ---------- */
.banner, .callout { display: flex; flex-wrap: wrap; gap: 11px; align-items: flex-start; padding: 12px 14px; border-radius: var(--radius); border: 1px solid; margin-bottom: 16px; font-size: 13px; }
.callout { flex-direction: column; gap: 3px; }
/* A banner says what is true, in one line (operator, 2026-09-21), so it centres
   its row and sits in the prototype's own 9px — the two files had disagreed on
   both since they were written, which a token comparison cannot see. */
.banner { align-items: center; padding: 9px 14px; }
/* Not a flex row: the tip's "i" belongs after the last word, and a flex item
   sits beside the whole block instead, which on a title long enough to wrap put
   it out on its own at the right (measured on the account page, 2026-09-21).
   It grows into the space the actions leave, and min-width:0 alone shrank it to
   one word a line in a narrow window. */
.banner .ttl { font-weight: 640; flex: 1 1 auto; min-width: 0; }
.banner.bad { background: var(--bad-soft); border-color: color-mix(in srgb, var(--bad) 28%, transparent); color: var(--bad); }
.banner.warn, .callout-idle { background: var(--warn-soft); border-color: #eddba6; color: #6b4a00; }
.banner.info { background: var(--accent-soft); border-color: var(--border-strong); color: var(--text); }
.banner.ok, .callout-live { background: var(--ok-soft); border-color: #bfe3cf; color: #0b5c3a; }
.banner .acts { margin-left: auto; display: flex; gap: 8px; flex: 0 0 auto; align-items: center; }
/* Wide enough for the longest thing one is asked for — "Why does it no longer
   need you?" measured 195px — because a placeholder cut mid-word reads as broken. */
.banner .acts .inp { width: 220px; max-width: 100%; }
/* AN ERROR HAS TO BE NOTICED. The operator typed a wrong password, then a wrong
   code, and asked for an error to be shown - it was being shown all along, in
   12.5px of a muted red with a 28px indent left over from an icon that no longer
   exists, which is a message that is technically present. It carries a bar in
   the failure colour now, at 13px and a little heavier, and the field it belongs
   to turns red with it. Its two hard-coded colours went to the tokens at the
   same time: they predate the palette round and were never updated. */
/* The line under the refusal: how many tries are left before the lock.
   Quieter than the refusal above it, and on its own line, because it is
   a warning about what happens next rather than what just happened. */
.errors-more { display: block; margin-top: 3px; color: var(--text-sub); font-weight: 450; }
.errors { margin: 0 0 12px; padding: 10px 12px; border-radius: 10px; background: var(--bad-soft);
    border: 1px solid color-mix(in srgb, var(--bad) 30%, transparent); border-left: 3px solid var(--bad);
    color: var(--bad); font-size: 13px; font-weight: 500; line-height: 1.45; }
.errors li + li { margin-top: 3px; }
/* The row immediately above the message is the one that was wrong. */
/* Marked where the page says which field is at fault, never from where the
   error block happens to sit. The rule used to be .acct-row:has(+ .errors),
   which marks whatever row precedes the message: on the sign-in form that is
   always the password, so "Type your e-mail." pointed at the password box
   (seen in a browser, 2026-09-22). */
.acct-row.bad .inp { border-color: var(--bad); box-shadow: 0 0 0 2px var(--bad-soft); }

/* ---------- forms ---------- */
/* Label and note on the left, control on the right; one rule per row. */
.formrow { display: grid; grid-template-columns: 230px 1fr; gap: 12px; align-items: start; padding: 11px 0; border-bottom: 1px solid #f2f2f2; }
.formrow:last-child { border-bottom: 0; }
.formrow .lab { font-size: 13px; font-weight: 550; padding-top: 6px; }
.formrow .lab small { display: block; font-weight: 400; color: var(--text-sub); margin-top: 2px; }
.formrow .ctl { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.inp, .ta {
    height: 30px; border: 1px solid var(--border-strong); border-radius: 7px; padding: 0 9px; font: inherit; font-size: 13px;
    background: #fff; color: var(--text); width: 110px; transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.inp:focus, .ta:focus { outline: 0; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.inp.w { width: 100%; max-width: 380px; }
.inp.m { width: 200px; }
.inp.s { width: 80px; }
.ta { width: 100%; max-width: 380px; height: auto; min-height: 90px; padding: 8px 9px; line-height: 1.5; resize: vertical; font-size: 12px; }
select.inp { padding-right: 6px; }
.check { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; padding-top: 6px; }
.check input { width: 15px; height: 15px; margin: 0; }
.formfoot { display: flex; gap: 8px; align-items: center; margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--border); }
.formfoot .sub { flex: 1; }
.saved { color: var(--ok); font-weight: 550; }
@media (max-width: 900px) { .formrow { grid-template-columns: minmax(0, 1fr); gap: 4px; } }

/* ---------- misc ---------- */
.facts { display: grid; grid-template-columns: max-content 1fr; gap: 0 16px; margin: 0 0 16px; font-size: 13px; }
.facts dt { color: var(--text-sub); padding: 8px 0; border-top: 1px solid #f2f2f2; }
.facts dd { margin: 0; padding: 8px 0; border-top: 1px solid #f2f2f2; }
.facts dt:first-of-type, .facts dd:first-of-type { border-top: 0; }
.empty { padding: 40px 16px; text-align: center; color: var(--text-sub); }
.empty .big { font-size: 15px; color: var(--text); font-weight: 600; margin-bottom: 5px; }
.muted { color: var(--text-sub); font-size: 12.5px; }
/* What an irreversible action costs, listed before it is taken. */
.impact { margin: 8px 0 12px; padding-left: 18px; font-size: 12.5px; color: var(--text-sub); }
.impact li + li { margin-top: 4px; }
.impact li.warn { color: #6b4a00; }
.warn { color: var(--warn); }
.danger, .text-danger { color: var(--bad); }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 16px; }
.pager { display: flex; align-items: center; gap: 12px; padding: 10px 12px; font-size: 12px; color: var(--text-sub); font-variant-numeric: tabular-nums; margin-bottom: 16px; }
.tick { color: var(--ok); } .cross { color: var(--bad); }

/* Keyboard focus is visible on every control; mouse clicks do not paint it. */
button:focus-visible, .btn:focus-visible, .chip:focus-visible, .nav a:focus-visible, .inp:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

#blazor-error-ui {
    display: none; position: fixed; inset: auto 0 0 0; z-index: 1000; padding: 0.7rem 1.25rem;
    background: var(--bad-soft); border-top: 1px solid var(--bad); color: var(--bad);
}
#blazor-error-ui .dismiss { cursor: pointer; float: right; }
/* The link out of the error bar. Without this it is the browser's default
   blue, underlined, on the bar's red ground - the one place in the panel a
   person sees an unstyled link, and only when something has already broken. */
#blazor-error-ui .reload { color: inherit; font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ---- conversations (ADR 0018): the thread, the grid, the definition lists ---- */
.convgrid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 16px; align-items: start; }
@media (max-width: 900px) { .convgrid { grid-template-columns: minmax(0, 1fr); } }
.msgs { display: flex; flex-direction: column; gap: 10px; }
.msg { max-width: 78%; border: 1px solid var(--border); border-radius: 12px; padding: 9px 12px; background: var(--card-2); }
.msg.out { align-self: flex-end; background: var(--accent-soft); border-color: var(--border-strong); }
.msg.unk { border-style: dashed; }
.msg .meta { font-size: 11px; color: var(--text-sub); margin-bottom: 3px; }
.msg .text { font-size: 13px; white-space: pre-wrap; }
tr.link { cursor: pointer; }
tr.link:hover td { background: var(--card-2); }
dl.kv { display: grid; grid-template-columns: 104px 1fr; gap: 6px 12px; margin: 0; font-size: 13px; }
dl.kv dt { color: var(--text-sub); } dl.kv dd { margin: 0; }

/* ==========================================================================
   The rest of the prototype's design language (docs/mockup/panel-prototype.html,
   2026-09-08): the top bar's search, bell and profile; menus and dialogs;
   the charts; the settings rows; the property page; the account pages.
   ========================================================================== */
/* Ink for the series being asked about, a grey for the one it is compared
   with. Lime is not spent on a chart: it has many marks and the signal has
   to stay rare. */
:root { --side-col: minmax(0, 380px); --c1: var(--ink); --c2: #a9a9a4; --grid: #e8e8e4; }

/* ---------- top bar: search, bell, profile ---------- */
.topbar-mid { position: absolute; left: 50%; transform: translateX(-50%); padding: 0 16px; max-width: 100%; }
.search { width: min(440px, 60vw); height: 32px; background: #303030; border: 0; border-radius: 8px; display: flex; align-items: center; gap: 8px; padding: 0 8px 0 10px; color: #e3e3e3; transition: background .12s, box-shadow .12s; }
.search:hover { background: #3a3a3a; }
.search:focus-within { background: #3a3a3a; box-shadow: 0 0 0 2px rgba(255, 255, 255, .28); }
.search .ico { flex: 0 0 auto; color: #9e9e9e; display: block; }
.search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: #fff; font: inherit; font-size: 13px; text-align: left; padding: 0; }
.search input::placeholder { color: #9e9e9e; }
.search .kbd { font-size: 11px; line-height: 1; color: #9e9e9e; border: 1px solid #4d4d4d; border-radius: 6px; padding: 3px 6px; white-space: nowrap; flex: 0 0 auto; }
.search .kind { font-size: 10px; color: #9a9a9a; border: 1px solid #4d4d4d; border-radius: 6px; padding: 2px 7px; white-space: nowrap; flex: 0 0 auto; }
.iconbtn { width: 32px; height: 32px; border-radius: 8px; background: transparent; border: 0; cursor: pointer; color: #c4c4c4; display: grid; place-items: center; position: relative; padding: 0; transition: background var(--fast) var(--ease), color var(--fast) var(--ease); }
.iconbtn:hover { background: #2f2f2f; }
.iconbtn svg { display: block; }
.iconbtn .pip { position: absolute; top: 1px; right: 0; min-width: 14px; height: 14px; border-radius: 7px; background: #e5484d; color: #fff; font-size: 9px; font-weight: 600; line-height: 1; display: grid; place-items: center; padding: 0 3px; border: 2px solid var(--topbar); font-variant-numeric: tabular-nums; letter-spacing: 0; }
.iconbtn.dryrun { color: #ffd166; background: rgba(255, 209, 102, .12); }
.iconbtn.stopped { color: #ff7b72; background: rgba(255, 123, 114, .14); }
.profile { height: 32px; display: flex; align-items: center; gap: 5px; padding: 0 7px 0 3px; border-radius: 8px; background: transparent; border: 0; cursor: pointer; color: #dcdcdc; margin-left: 2px; transition: background var(--fast) var(--ease); }
.profile:hover { background: #2f2f2f; }
.profile .av { width: 26px; height: 26px; border-radius: 50%; background: #3a4252; color: #e8e8e8; display: grid; place-items: center; font-size: 10px; font-weight: 700; flex: 0 0 auto; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .1); }
.profile .cv { font-size: 9px; opacity: .55; margin-left: 1px; }
.pmenu { position: absolute; right: 12px; top: 48px; min-width: 210px; background: var(--card); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 28px rgba(0, 0, 0, .24); padding: 5px; z-index: 130; color: var(--text); }
.pmenu .hd2 { padding: 9px 10px 8px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.pmenu .hd2 b { display: block; font-size: 13px; }
.pmenu .hd2 span { font-size: 12px; color: var(--text-sub); }
.pmenu button { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 7px 10px; border-radius: 7px; font-size: 13px; cursor: pointer; color: var(--text); height: auto; font-weight: 450; }
.pmenu button:hover { background: var(--card-2); }
.pmenu form { margin: 0; }
.menubackdrop { position: fixed; inset: 0; z-index: 120; background: transparent; }
.nwrap { position: relative; display: inline-flex; }
.nmenu { position: absolute; right: 0; top: calc(100% + 4px); width: 400px; background: var(--card); color: var(--text); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 28px rgba(0, 0, 0, .24); z-index: 130; overflow: hidden; text-align: left; font-size: 13px; line-height: 1.45; }
.nmenu .nhd { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.nmenu .nhd b { font-size: 13px; }
.nmenu .nhd span { font-size: 12px; color: var(--text-sub); }
.nlist { max-height: min(60vh, 420px); overflow-y: auto; }
.nrow { display: grid; grid-template-columns: 18px minmax(0, 1fr) auto; gap: 8px; align-items: start; padding: 10px 12px; border-bottom: 1px solid #f2f2f2; cursor: pointer; transition: background var(--fast) var(--ease); }
.nlist .nrow:last-child { border-bottom: 0; }
.nrow:hover { background: var(--card-2); }
.nrow.unread { background: #f7f9ff; }
.nrow.unread:hover { background: #eef2ff; }
.nrow .mk { width: 8px; height: 8px; border-radius: 50%; margin-top: 5px; background: var(--idle); justify-self: center; }
.nrow .mk.review, .nrow .mk.health { background: var(--bad); }
.nrow .mk.sla, .nrow .mk.quota { background: #d9a400; }
.nrow .mk.feed { background: var(--accent); }
.nrow .mk.switch { background: var(--c2); }
.nrow .mk.key { background: #d9a400; }
.nrow .tx { min-width: 0; }
.nrow .tx b { display: block; font-size: 13px; font-weight: 550; line-height: 1.35; }
.nrow.unread .tx b { font-weight: 650; }
.nrow .tx span { display: block; font-size: 12px; color: var(--text-sub); line-height: 1.4; margin-top: 1px; }
.nrow .when { font-size: 11.5px; color: var(--text-mute); white-space: nowrap; font-variant-numeric: tabular-nums; margin-top: 2px; }
.nrow.pin { border-bottom: 1px solid var(--border); }
.nrow.pin.dryrun { background: var(--warn-soft); } .nrow.pin.dryrun .tx b { color: var(--warn); } .nrow.pin.dryrun .mk { background: var(--warn); }
.nrow.pin.stopped { background: var(--bad-soft); } .nrow.pin.stopped .tx b { color: var(--bad); } .nrow.pin.stopped .mk { background: var(--bad); }
.nmenu .nft { padding: 8px 12px; border-top: 1px solid var(--border); background: var(--card-2); font-size: 11.5px; color: var(--text-sub); }
.sdrop { position: absolute; top: calc(100% + 6px); left: 16px; right: 16px; background: var(--card); color: var(--text); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 12px 32px rgba(0, 0, 0, .22); overflow: hidden; z-index: 130; }
.sresults { max-height: min(56vh, 400px); overflow-y: auto; padding: 6px; }
.sresults .grp { font-size: 10px; font-weight: 600; letter-spacing: .06em; color: var(--text-mute); text-transform: uppercase; padding: 6px 10px 5px; }
.sresults .pitem + .grp { margin-top: 6px; padding-top: 9px; border-top: 1px solid #f2f2f2; }
.pitem { display: block; padding: 8px 10px 9px; border-radius: 8px; cursor: pointer; transition: background var(--fast) var(--ease); }
.pitem:hover, .pitem.psel { background: var(--accent-soft); }
.pitem .tx { display: block; min-width: 0; }
.pitem .tx b { font-size: 12.5px; font-weight: 600; line-height: 1.35; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pitem .tx span { font-size: 11.5px; color: var(--text-sub); line-height: 1.35; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; }
.sfoot { padding: 8px 12px; border-top: 1px solid var(--border); background: var(--card-2); font-size: 11px; color: var(--text-sub); }
.sempty { padding: 18px 12px; text-align: center; color: var(--text-sub); font-size: 12.5px; }
.lockic { font-size: 10px; opacity: .5; }
.navfoot { padding: 8px 12px 12px; }
.navfoot a { display: flex; align-items: center; gap: 8px; height: 28px; padding: 0 4px 0 8px; border-radius: 8px; font-size: 13px; font-weight: 550; color: var(--text); transition: background var(--fast) var(--ease); }
/* .navfoot a:hover paints nothing either, for the same reason. */
/* The Settings row's icon box. Without this it inherits its height from the
   line box - measured 2026-09-21 at 20.8px against the 16px every other row
   gets - and the icon sits at the top of it, 2.42px above the label's centre.
   The nav's own rows have had this rule all along; the foot never did. */
.navfoot a .ic { width: 16px; height: 16px; flex: 0 0 16px; display: grid; place-items: center; color: #4a4a4a; }
.navfoot a .ic svg { display: block; }
.navfoot a.active { background: var(--sidebar-active); color: var(--sidebar-active-text); }
.navfoot a .ic { width: 16px; height: 16px; flex: 0 0 16px; display: grid; place-items: center; color: #4a4a4a; }

/* ---------- account pages (sign-in, first run, 2FA) ---------- */
/* The sign-in screen is the one page with nothing to operate, so it is the one
   that carries the brand at full size: Ink ground, Lime mark, and a galaxy
   turning behind the card (wwwroot/galaxy.js). Everything a person reads still
   sits on Paper. */
/* The canvas is fixed, so anything the wrap does not cover would show the
   panel's own light ground under it. */
/* Space is black on this one screen (operator, 2026-09-22). --ink is a dark
   grey and stays exactly as it is everywhere else; beside a star field a grey
   ground reads as fog. */
body:has(.acct-wrap) { background: #000; }
.acct-wrap { position: relative; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; padding: 40px 16px; background: #000; }
#galaxy { position: fixed; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; }
/* Everything above the canvas sits in its own layer; the canvas never takes a
   click, so a mis-sized canvas can never swallow the form. */
.acct-wrap > *:not(#galaxy) { position: relative; z-index: 1; }
.acct-brand .lockup { display: inline-flex; align-items: center; gap: 8px; }
.acct-brand .logo { height: 16px; aspect-ratio: 250/160; display: inline-block; background: var(--lime); transform: translateY(-1px);
    -webkit-mask: url(ha-mark.png) center/contain no-repeat; mask: url(ha-mark.png) center/contain no-repeat; }
.acct-brand .name { font-weight: 600; font-size: 15px; color: var(--topbar-text); }
/* 400px, not 520: two fields and one button is a narrow column, and at 520 the
   e-mail box ran 464px across a card with nothing else in it (operator,
   2026-09-21). The QR and the recovery codes need the old width and ask for it. */
.acct-card { background: var(--card); border-radius: var(--radius); padding: 28px; width: min(400px, 100%);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3), 0 0 0 1px rgba(255, 255, 255, .06); }
/* The card is one element in the layout, shared by every account page, so the
   two that hold a QR or the recovery codes ask for the old width by what is in
   them rather than by a flag threaded through the layout. */
.acct-card:has(.qr-row), .acct-card:has(.codes) { width: min(520px, 100%); }
.acct-card h1 { margin: 0 0 18px; font-size: 21px; font-weight: 600; letter-spacing: -.2px; }
.acct-card .sub { margin-bottom: 14px; }
.acct-row { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.acct-row label { font-size: 12.5px; font-weight: 550; }
.acct-row .inp { height: 38px; }
/* The one action on the page takes the width of the card. */
.acct-go { width: 100%; height: 40px; justify-content: center; margin-top: 4px; font-size: 13px; }
/* A code is read back digit by digit, so it is set wide and loose and given the
   whole field to sit in. The old one was a 140px box with a font-family nobody
   loads any more (var(--mono) went when the panel went to one face). */
.acct-row .otp { width: 100%; height: 46px; font-size: 19px; font-weight: 600; letter-spacing: .34em;
    text-align: center; text-indent: .34em; font-variant-numeric: tabular-nums; }
/* The way out, which appears only once somebody needs it: a rule, a small
   heading and one sentence. It is part of the same card, not a second card and
   not a banner - a person three wrong codes deep does not need a notice, they
   need the next thing to try. */
/* A way back under the action, for the one screen that has one. */
.acct-after { margin-top: 12px; font-size: 12.5px; text-align: center; }
.acct-after a { color: var(--text-sub); text-decoration: underline; text-underline-offset: 2px; }
.acct-more { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border); }
.acct-more h2 { margin: 0 0 4px; font-size: 14px; font-weight: 600; }
.acct-more p { margin: 0; font-size: 12.5px; color: var(--text-sub); line-height: 1.5; }
.acct-foot-row { display: flex; gap: 8px; align-items: center; margin-top: 16px; flex-wrap: wrap; }
/* On the Ink ground, not on Paper: its own grey rather than --text-mute. */
.acct-foot { font-size: 11.5px; color: #8a8a86; }
.qr-row { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
.qr { width: 200px; height: 200px; flex: 0 0 auto; border: 1px solid var(--border); border-radius: 8px; padding: 8px; background: #fff; }
.qr svg { width: 100%; height: 100%; display: block; }
.codes { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px 18px; font-size: 13px; margin: 8px 0 14px; }

/* ---------- menus, dialogs, tabs, switches ---------- */
.crumb { font-size: 12px; color: var(--text-sub); margin-bottom: 6px; }
.crumb a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
.crumb .back { display: inline-block; font-size: 16px; line-height: 1; text-decoration: none; padding: 0 6px 2px 0; cursor: pointer; }
.tabs { display: flex; gap: 2px; flex-wrap: wrap; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
.tabs button { background: none; border: 0; padding: 8px 12px; font-size: 13px; color: var(--text-sub); cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; border-radius: 0; height: auto; font-weight: 450; }
.tabs button.on { color: var(--text); font-weight: 600; border-bottom-color: #1a1a1a; }
.tabs button:hover { color: var(--text); background: none; }
.sel { height: 28px; border-radius: 8px; border: 0; background: #e3e3e3; font-size: 12px; font-weight: 550; padding: 0 6px; color: var(--text); cursor: pointer; font-family: inherit; }
.sel:hover { background: #dadada; }
.srch { height: 28px; border-radius: 8px; border: 0; background: #e3e3e3; font-size: 12px; padding: 0 10px; min-width: 180px; color: var(--text); font-family: inherit; }
.switch { width: 38px; height: 22px; border-radius: 999px; background: #cfcfcf; position: relative; border: 0; cursor: pointer; flex: 0 0 auto; padding: 0; transition: background var(--med) var(--ease); }
.switch:hover { background: #c4c4c4; }
.switch i { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .2); transition: left var(--med) var(--ease); }
.switch.on, .switch.on:hover { background: var(--ok); } .switch.on i { left: 18px; }
.seg { display: inline-flex; background: #ececec; border-radius: 999px; padding: 2px; }
.seg button { border: 0; background: none; height: 26px; padding: 0 14px; border-radius: 999px; font-size: 12.5px; cursor: pointer; color: var(--text-sub); font-weight: 550; }
.seg button.on { background: #fff; color: var(--text); box-shadow: 0 1px 2px rgba(0, 0, 0, .12); }
.seg.sm button { height: 22px; padding: 0 10px; font-size: 12px; }
.scrim { position: fixed; inset: 0; background: rgba(20, 20, 20, .42); z-index: 200; display: grid; place-items: center; padding: 20px; animation: fade var(--med) var(--ease); }
.modal { background: var(--card); border-radius: 12px; max-width: 520px; width: 100%; box-shadow: 0 12px 40px rgba(0, 0, 0, .28); overflow: hidden; animation: rise var(--med) var(--ease); }
.modal .mh { padding: 15px 18px; border-bottom: 1px solid var(--border); font-weight: 640; font-size: 15px; }
.modal .mb { padding: 18px; }
.modal .mf { padding: 13px 18px; border-top: 1px solid var(--border); background: var(--card-2); display: flex; gap: 8px; justify-content: flex-end; }
.menuwrap { position: relative; display: inline-block; }
.statusbtn { height: 32px; padding: 0 10px 0 12px; border-radius: 8px; border: 1px solid var(--border-strong); background: #fff; cursor: pointer; font-size: 13px; font-weight: 550; display: inline-flex; align-items: center; gap: 8px; }
.statusbtn:hover { background: #f6f6f6; }
.statusbtn .car { opacity: .5; font-size: 10px; }
.menu { position: absolute; right: 0; top: 36px; min-width: 240px; background: var(--card); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 28px rgba(0, 0, 0, .16); padding: 5px; z-index: 120; text-align: left; animation: pop var(--med) var(--ease); }
.menu .grp { font-size: 10.5px; font-weight: 600; letter-spacing: .06em; color: var(--text-mute); padding: 7px 9px 3px; text-transform: uppercase; }
.menu button { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 7px 9px; border-radius: 7px; font-size: 13px; cursor: pointer; height: auto; font-weight: 450; }
.menu button:hover { background: var(--card-2); }
.menu button.danger { color: var(--bad); background: none; }
.menu button.danger:hover { background: var(--bad-soft); }
.menu hr { border: 0; border-top: 1px solid var(--border); margin: 5px 2px; }
@keyframes pop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes rise { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
.nmenu, .pmenu { animation: pop var(--med) var(--ease); }

/* ---------- settings rows, tips ---------- */
.setmeta { margin-top: 5px; font-variant-numeric: tabular-nums; }
.tipdot { display: inline-grid; place-items: center; width: 14px; height: 14px; border-radius: 50%; border: 1px solid var(--border); color: var(--text-mute); font-size: 9.5px; font-weight: 650; font-style: normal; line-height: 1; margin-left: 6px; vertical-align: 1px; cursor: default; user-select: none; }
.tipdot:hover, .tipdot:focus-visible { background: #ebebeb; border-color: var(--border-strong); color: var(--text); outline: 0; }
#tip { position: fixed; z-index: 400; max-width: 300px; background: var(--card); color: var(--text); font-size: 12.5px; font-weight: 450; line-height: 1.45; padding: 9px 11px; border-radius: 10px; border: 1px solid var(--border); box-shadow: 0 12px 32px rgba(0, 0, 0, .12), 0 2px 6px rgba(0, 0, 0, .06); pointer-events: none; opacity: 0; transform: translateY(4px); transition: opacity var(--med) var(--ease), transform var(--med) var(--ease); }
#tip.on { opacity: 1; transform: none; }
.scope { display: flex; gap: 9px; align-items: flex-start; margin-top: 14px; padding: 10px 12px; border-radius: 8px; background: #f4f6fb; border: 1px solid #dde3f0; font-size: 12.5px; color: #3c4763; line-height: 1.5; }
.scope .ic { flex: 0 0 auto; opacity: .7; font-size: 13px; line-height: 1.5; }
.scope.now { background: var(--bad-soft); border-color: #f3c9c4; color: #7a1a12; }
.scope.back { background: var(--warn-soft); border-color: #eddba6; color: #6b4a00; }
.editfoot { display: flex; gap: 8px; align-items: center; margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--border); }
@keyframes flash { 0%, 35% { background: var(--accent-soft); } 100% { background: transparent; } }
.formrow.flash { animation: flash 1.8s var(--ease); border-radius: 8px; }

/* ---------- charts (Home statistics) ---------- */
.kpi { background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow); padding: 16px; display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; row-gap: 4px; align-items: center; }
.kpi .k { grid-column: 1/-1; font-size: 13px; font-weight: 600; color: var(--text); line-height: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi .v { font-size: 13px; font-weight: 600; color: var(--text); line-height: 16px; min-width: 0; }
.kpi .v .dl { font-weight: 450; margin-left: 6px; font-size: 12px; }
.kpi svg { display: block; }
.lc { display: flex; }
.lc-y { flex: 0 0 auto; display: flex; flex-direction: column; justify-content: space-between; padding-right: 8px; text-align: right; font-size: 11px; line-height: 14px; color: var(--text-sub); font-variant-numeric: tabular-nums; }
.lc-plot { flex: 1; min-width: 0; }
.lc-plot svg { display: block; width: 100%; overflow: visible; }
.lc-x { position: relative; height: 20px; }
.lc-x span { position: absolute; top: 6px; font-size: 11px; line-height: 14px; color: var(--text-sub); white-space: nowrap; transform: translateX(-50%); }
.lc-x span.first { transform: none; }
.lc-x span.last { transform: translateX(-100%); }
.chartcard { background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow); padding: 16px; margin-bottom: 16px; }
.chartcard h3 { margin: 0; font-size: 13px; font-weight: 600; line-height: 16px; text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px; }
.chartcard .big { font-size: 20px; font-weight: 600; letter-spacing: -.1666px; margin: 6px 0 10px; line-height: 24px; }
.chartcard .legend2 { display: flex; gap: 16px; justify-content: center; font-size: 12px; color: var(--text-sub); margin-top: 8px; }
.chartcard .legend2 i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 6px; }
.chartgrid, .chartgrid3 { display: grid; gap: 16px; margin-bottom: 16px; }
.chartgrid { grid-template-columns: minmax(0, 1fr) var(--side-col); }
.chartgrid3 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) var(--side-col); }
@media (max-width: 1100px) { .chartgrid, .chartgrid3 { grid-template-columns: minmax(0, 1fr); } }
.brk { width: 100%; border-collapse: collapse; font-size: 13px; }
.brk td { padding: 9px 10px; border: 0; height: auto; white-space: normal; }
.brk tr:nth-child(odd) { background: var(--card-2); }
.brk td:first-child { color: var(--accent); }
.brk td:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.brk tr.tot td { font-weight: 600; }
.brk tr.tot td:first-child { color: var(--text); }
.barlist { display: grid; gap: 9px; }
.barlist .r { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; align-items: center; font-size: 12.5px; }
.barlist .nm { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.barlist .tr { height: 16px; background: var(--card-2); border-radius: 3px; overflow: hidden; margin-top: 3px; }
.barlist .tr i { display: block; height: 100%; background: var(--c1); border-radius: 3px; }
.barlist .vv { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-sub); white-space: nowrap; }
.fbar { padding: 12px; border-bottom: 1px solid var(--border); }
.frow { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.frow + .frow { margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--border); }
.datebtn { height: 28px; border-radius: 8px; border: 1px solid var(--border-strong); background: #fff; font-size: 12.5px; padding: 0 11px; cursor: pointer; display: inline-flex; align-items: center; gap: 7px; }
.datebtn:hover { background: #f4f4f4; }
.datebtn .rng { font-weight: 600; }
.datebtn .dc { color: var(--text-mute); font-size: 11.5px; }
.fchip { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 6px 0 10px; border-radius: 999px; background: var(--accent-soft); color: var(--accent); font-size: 12px; font-weight: 550; }
.fchip button { border: 0; background: none; cursor: pointer; color: inherit; font-size: 13px; line-height: 1; opacity: .65; padding: 0 2px; height: auto; }
.fchip button:hover { opacity: 1; background: none; }
.calwrap { position: relative; display: inline-block; }
.cal { position: absolute; top: 34px; left: 0; z-index: 140; background: var(--card); border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 12px 34px rgba(0, 0, 0, .2); padding: 12px; width: 284px; }
.calhd { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.calhd b { font-size: 13px; }
.calnav { width: 26px; height: 26px; border-radius: 7px; border: 1px solid var(--border); background: #fff; cursor: pointer; font-size: 12px; line-height: 1; padding: 0; }
.calnav:disabled { opacity: .35; cursor: not-allowed; }
.calgrid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.calgrid .dow { font-size: 10px; color: var(--text-mute); text-align: center; padding: 4px 0; font-weight: 600; }
.calgrid button { height: 32px; border: 0; background: none; border-radius: 7px; font-size: 12.5px; cursor: pointer; font-variant-numeric: tabular-nums; color: var(--text); padding: 0; justify-content: center; }
.calgrid button:hover:not(:disabled) { background: var(--card-2); }
.calgrid button:disabled { color: #c9c9c9; cursor: not-allowed; opacity: 1; }
.calgrid button.in { background: var(--accent-soft); border-radius: 0; }
.calgrid button.edge { background: var(--ink); color: var(--paper); border-radius: 7px; font-weight: 650; }
.calfoot { display: flex; gap: 8px; align-items: center; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.calfoot .hint2 { flex: 1; font-size: 11.5px; color: var(--text-sub); }
.presets { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 10px; }
.presets button { border: 1px solid var(--border); background: #fff; border-radius: 999px; height: 24px; padding: 0 9px; font-size: 11.5px; cursor: pointer; }
.legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: var(--text-sub); }
.legend i { width: 9px; height: 9px; border-radius: 2px; display: inline-block; margin-right: 5px; }

/* ---------- property page, logs, threads ---------- */
.kv { display: grid; grid-template-columns: 150px 1fr; gap: 7px 14px; font-size: 13px; margin: 0; }
.kv dt { color: var(--text-sub); } .kv dd { margin: 0; }
.fd { display: grid; grid-template-columns: 132px 1fr; gap: 0 16px; font-size: 13px; margin: 0; }
.fd dt { color: var(--text-sub); padding: 9px 0; border-top: 1px solid #f2f2f2; }
.fd dd { margin: 0; padding: 9px 0; border-top: 1px solid #f2f2f2; min-width: 0; }
.fd dt:first-of-type, .fd dd:first-of-type { border-top: 0; padding-top: 0; }
.fd .big { font-size: 15px; font-weight: 600; }
.chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chips span { background: var(--card-2); border: 1px solid var(--border); border-radius: 6px; padding: 2px 7px; font-size: 12px; color: var(--text-sub); }
.bar { height: 7px; border-radius: 4px; background: #ececec; overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--signal); }
.bar.ok > i { background: var(--ok); } .bar.warn > i { background: #d9a400; } .bar.bad > i { background: var(--bad); }
.steps { list-style: none; margin: 0; padding: 0; }
.steps li { display: flex; gap: 10px; align-items: flex-start; padding: 8px 0; border-bottom: 1px solid #f2f2f2; font-size: 13px; }
.steps li:last-child { border-bottom: 0; }
.steps .n { width: 20px; flex: 0 0 20px; text-align: right; color: var(--text-mute); font-size: 12px; font-variant-numeric: tabular-nums; }
.steps .t { flex: 1; }
.steps .when { color: var(--text-mute); font-size: 12px; font-variant-numeric: tabular-nums; }
.tg { background: #0f1720; color: #d7e3f0; border-radius: var(--radius); padding: 13px 15px; font-size: 12px; line-height: 1.6; white-space: pre-wrap; border: 1px solid #223; }
.drop { border: 2px dashed var(--border-strong); border-radius: var(--radius); padding: 24px; text-align: center; color: var(--text-sub); background: var(--card-2); }
.drop b { color: var(--text); }
.hero { display: grid; grid-template-columns: minmax(0, 50%) minmax(0, 1fr); overflow: hidden; }
.hero .photowrap { aspect-ratio: auto; height: auto; margin: 0 14px 0 0; border-radius: 0 10px 10px 0; }
.hero .photowrap img { position: absolute; inset: 0; }
.hero .facts { padding: 22px 24px 22px 10px; min-height: 392px; display: flex; flex-direction: column; justify-content: center; margin: 0; grid-template-columns: none; }
@media (max-width: 900px) { .hero { grid-template-columns: minmax(0, 1fr); } .hero .photowrap { aspect-ratio: 4/3; margin: 0; border-radius: 0; } .hero .photowrap img { position: static; } .hero .facts { min-height: 0; padding: 18px 20px; } }
.photowrap { position: relative; border-radius: 8px; overflow: hidden; background: #e8ecf3; aspect-ratio: 4/3; }
.photowrap img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pnav { position: absolute; top: 50%; transform: translateY(-50%); width: 30px; height: 30px; border-radius: 50%; border: 0; background: rgba(20, 20, 20, .55); color: #fff; font-size: 17px; line-height: 1; cursor: pointer; display: grid; place-items: center; padding: 0; }
.pnav:hover { background: rgba(20, 20, 20, .8); }
.pnav.prev { left: 8px; } .pnav.next { right: 8px; }
.pcount { position: absolute; right: 8px; bottom: 8px; background: rgba(20, 20, 20, .6); color: #fff; font-size: 11px; padding: 2px 8px; border-radius: 999px; font-variant-numeric: tabular-nums; }
.pfail { position: absolute; inset: 0; display: grid; place-items: center; color: var(--text-sub); background: var(--card-2); font-size: 12px; text-align: center; padding: 20px; }
.ti { width: 100%; border: 1px solid var(--border-strong); border-radius: 8px; padding: 0 11px; height: 36px; font: inherit; font-size: 15px; font-weight: 600; background: #fff; }
.ta.copy { font-family: inherit; font-size: 13px; max-width: none; min-height: 104px; }
.cnt { font-size: 11.5px; color: var(--text-mute); margin-top: 4px; text-align: right; font-variant-numeric: tabular-nums; }
.cnt.over { color: var(--bad); font-weight: 600; }
.log { list-style: none; margin: 0; padding: 0; position: relative; }
.log li { display: grid; grid-template-columns: 132px 20px 1fr 120px; gap: 12px; align-items: start; padding: 11px 0; border-bottom: 1px solid #f2f2f2; }
.log li:last-child { border-bottom: 0; }
.log li.row { cursor: pointer; }
.log li.row:hover { background: #fafbff; }
.log li.open { background: #f7f9ff; }
.log .caret { font-size: 10px; color: var(--text-mute); transition: transform .12s; display: inline-block; }
.log li.open .caret { transform: rotate(90deg); }
.log .when { font-size: 12.5px; color: var(--text-sub); font-variant-numeric: tabular-nums; white-space: nowrap; }
.log .mk { width: 20px; text-align: center; font-size: 12px; line-height: 1.5; }
.log .what { min-width: 0; }
.log .what b { font-size: 13px; font-weight: 600; }
.log .what .d { font-size: 12.5px; color: var(--text-sub); margin-top: 2px; }
.log .who { font-size: 12.5px; text-align: right; white-space: nowrap; }
.log .who .sys { color: var(--text-mute); }
.log .who .person { background: var(--accent-soft); color: var(--accent); border-radius: 999px; padding: 2px 8px; font-weight: 550; }
.log.clamp { max-height: 520px; overflow-y: auto; }
@media (max-width: 820px) { .log li { grid-template-columns: minmax(0, 1fr); gap: 3px; } .log .who { text-align: left; } .log .mk { display: none; } }
.cdet { grid-column: 1/-1; margin-top: 10px; padding: 14px; border-radius: 9px; background: var(--card-2); border: 1px solid var(--border); }
.cdet .cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
@media (max-width: 900px) { .cdet .cols { grid-template-columns: minmax(0, 1fr); } }
.cdet dl { display: grid; grid-template-columns: 104px 1fr; gap: 5px 10px; font-size: 12.5px; margin: 0; }
.cdet dt { color: var(--text-sub); } .cdet dd { margin: 0; }
.cdet .secttl { font-size: 10.5px; font-weight: 600; letter-spacing: .06em; color: var(--text-mute); text-transform: uppercase; margin-bottom: 7px; }
.thread { display: flex; flex-direction: column; gap: 7px; margin-top: 12px; padding: 12px 6px 0 0; border-top: 1px solid var(--border); max-height: 320px; overflow-y: auto; }
.tmsg { max-width: 82%; border-radius: 10px; padding: 7px 10px; font-size: 12.5px; }
.tmsg.in { background: #fff; border: 1px solid var(--border); align-self: flex-start; }
.tmsg.out { background: var(--accent-soft); border: 1px solid var(--border-strong); align-self: flex-end; }
.tmsg .m { font-size: 10.5px; color: var(--text-mute); margin-bottom: 2px; }
.locked { padding: 60px 20px; text-align: center; max-width: 520px; margin: 0 auto; }
.locked .lk { font-size: 30px; }
.locked h2 { margin: 12px 0 6px; font-size: 17px; }
.locked p { color: var(--text-sub); margin: 0; }
tbody tr.click { cursor: pointer; transition: background var(--fast) var(--ease); }
tbody tr.click:hover { background: #fafbff; }
.tw { max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pager { border-top: 1px solid var(--border); margin-bottom: 0; }
.pager .spacer { flex: 1; }
.pager label { display: inline-flex; align-items: center; gap: 6px; }
.pager .btn, .pager button { padding: 0 8px; font-size: 15px; line-height: 1; }
.note { font-size: 12px; color: var(--text-sub); }

/* ==========================================================================
   A PHONE. The twin of the block at the foot of docs/mockup/panel-prototype.html,
   and measured there before either was written: at 375px the 240px sidebar left
   the content 135px wide, and the top bar alone asked for 563px, so eleven of
   the fifteen pages read scrolled sideways.

   The reference admin answers this by turning its sidebar into a drawer and
   putting everything else in one column, and the brand adds nothing new here -
   the same ink, paper, lime and Manrope, narrower. The tables already sit in
   their own scroller and stay as they are: a table is read by scrolling it, not
   by folding it into cards nobody can compare.

   860px, not 768: below 860 the sidebar and a two-column grid together leave
   each column under 300px, which is narrower than a metric card needs.
   ========================================================================== */
.navtoggle { display: none; width: 40px; height: 40px; margin-left: 6px; border: 0; border-radius: 8px;
    background: transparent; color: #e8e8e6; cursor: pointer; place-items: center; flex: 0 0 auto; }
.navtoggle:hover { background: #2f2f2f; }
.navtoggle:focus-visible { outline: 2px solid #6f6f6f; outline-offset: 1px; }
.scrim { display: none; }

@media (max-width: 860px) {
    /* The bar: a way in, the mark, the search, and who you are. */
    .navtoggle { display: grid; }
    .brand { width: auto; flex: 0 0 auto; padding: 0 4px 0 6px; }
    .brand .name { display: none; }
    .topbar-mid { position: static; transform: none; flex: 1; min-width: 0; padding: 0 8px; max-width: none; }
    .search { width: 100%; }
    .search .kbd { display: none; }
    .topbar-right { padding-right: 8px; }

    /* The sidebar is a drawer. It is off-screen until asked for, and the scrim
       is what makes tapping anywhere else close it. */
    .sidebar { width: 282px; transform: translateX(-100%); transition: transform var(--med) var(--ease);
        box-shadow: 0 10px 40px rgba(0, 0, 0, .2); }
    body.nav-open .sidebar { transform: none; }
    .scrim { display: block; position: fixed; inset: var(--topbar-h) 0 0 0; background: rgba(0, 0, 0, .34);
        opacity: 0; pointer-events: none; transition: opacity var(--med) var(--ease); z-index: 45; }
    body.nav-open .scrim { opacity: 1; pointer-events: auto; }
    body.nav-open { overflow: hidden; }

    /* One column, and a 16px gutter on both sides. */
    .main { margin-left: 0; padding: 16px 16px 48px; }
    /* minmax(0,1fr), not 1fr: a bare 1fr is minmax(AUTO,1fr), and a chart or a
       table wider than the screen then forces the track wider than the page.
       Measured at 320px, where three chart cards came out 315px in a 288px box. */
    .g2, .g3, .g4 { grid-template-columns: minmax(0, 1fr); }
    .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .convgrid { grid-template-columns: minmax(0, 1fr); }
    .pagehead { gap: 10px; }
    .pagehead .spacer { display: none; }
    .filters { padding: 10px; }

    /* A finger is not a pointer. 28px rows are comfortable with a mouse and too
       small to hit with a thumb; these are the ones a person taps. The panel
       styles plain <button> as well as .btn, so both are named. */
    button, .btn, .chip, .sel { height: auto; min-height: 38px; padding-top: 0; padding-bottom: 0; }
    button.sm, .btn.sm, .chip.sm { min-height: 32px; }
    .inp, .ta { height: auto; min-height: 38px; width: 100%; }
    .inp.w { max-width: none; }
    /* A 230px label column beside its control does not fit in 343px: the row was
       clipping by up to 128px on five pages. The label goes above the control. */
    .formrow { grid-template-columns: minmax(0, 1fr); gap: 6px; }
    .formrow .lab { padding-top: 0; }
    /* .seg button is more specific than the button rule above, so it needs its own. */
    .seg button { height: 34px; }
    .nav a, .navfoot a { height: 40px; }
    .sect { padding-top: 18px; }
    .tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
    .tabs::-webkit-scrollbar { display: none; }
    .tabs button { white-space: nowrap; padding: 10px 12px; }
}

/* ==========================================================================
   A BIG SCREEN. The content stops at 1320px so a line of 13px text stays
   readable, and until now it stopped there glued to the sidebar: measured, a
   1920 monitor left 360px of the window empty on the right, a 2560 left 1000
   and an ultrawide 1880. The column is centred in the space the sidebar leaves
   instead, so the gap either side of it is the same.

   The cap itself stays. 1320px is already a long line at this size, and a
   column that grows with the monitor is the thing every admin stops at.

   max() rather than the calc alone: the query reads the viewport and the calc
   reads the body, which is narrower by the scrollbar, so at the boundary the
   calc alone would put the content under the sidebar.
   ========================================================================== */
@media (min-width: 1600px) {
    .main { margin-left: max(var(--sidebar-w), calc(var(--sidebar-w) + (100% - var(--sidebar-w) - 1320px) / 2)); }
}

/* A phone held upright: one metric to a row reads better than two 160px ones. */
@media (max-width: 520px) {
    .metrics { grid-template-columns: minmax(0, 1fr); }
    .main { padding: 14px 16px 44px; }
    .pagehead h1 { font-size: 18px; line-height: 22px; }
    /* A 150px term column beside its value does not fit a 288px card, which is
       what a 320px phone leaves: measured, the list came out 304px wide in it.
       The term goes above its value, the way a form row already does. */
    .kv, .facts { grid-template-columns: minmax(0, 1fr); gap: 0; }
    .kv dt, .facts dt { padding-bottom: 0; border-top: 0; }
    .kv dd, .facts dd { padding-top: 2px; border-top: 0; margin-bottom: 8px; }
}
