/* ===========================================================
   AttendIQ — shared stylesheet

   Deliberately plain business software. The previous version
   was dark with neon accents, a display typeface, 18px corners
   and gradient glows, which read as a demo rather than a tool
   people are made to use every morning. HR products this sits
   beside — Zoho People, BambooHR, Keka — all look the same way
   for the same reason: light ground, one restrained blue, 4px
   corners, hairline borders, no shadow to speak of, and the
   system typeface. Boring is the point. Nothing here should
   draw attention away from the numbers.
   =========================================================== */

:root{
  /* One typeface, the one the operating system already uses. */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, "Noto Sans", sans-serif;
  --font-mono: "SF Mono", "Cascadia Mono", Consolas, "Liberation Mono", monospace;

  /* Surfaces: a light grey page, white panels sitting on it. */
  --page: #f4f6f8;
  --surface: #ffffff;
  --surface-2: #f7f9fb;
  --surface-3: #eef1f5;

  --border: #e1e5ea;
  --border-strong: #cdd4dd;

  --text: #1a1f26;
  --text-2: #4a5560;
  --text-muted: #79838f;

  /* One blue, used for anything actionable and nothing else. */
  --primary: #1c64d1;
  --primary-dark: #164fa8;
  --primary-soft: #e8f0fc;
  --primary-line: #b9d2f5;

  /* Status. Muted enough to sit in a dense table without shouting. */
  --ok: #0f8a5f;        --ok-soft: #e6f5ee;   --ok-line: #b6e2ce;
  --warn: #b87500;      --warn-soft: #fdf3e3; --warn-line: #f0d9ab;
  --danger: #c93a39;    --danger-soft: #fdecec; --danger-line: #f4c4c3;
  --info: #1c64d1;      --info-soft: #e8f0fc; --info-line: #b9d2f5;
  --violet: #6b4fbb;    --violet-soft: #efeaf9; --violet-line: #d3c6ee;

  --shadow: 0 1px 2px rgba(16,24,40,0.05);
  --shadow-md: 0 2px 6px rgba(16,24,40,0.08);
  --shadow-lg: 0 10px 28px rgba(16,24,40,0.14);

  --radius: 6px;
  --radius-sm: 4px;
  --sidebar: 232px;
  --topbar: 56px;
}

*, *::before, *::after{ box-sizing: border-box; }
html{ color-scheme: light; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration: 0.001ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

body{
  margin: 0;
  min-height: 100vh;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--page);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4{ margin: 0; font-weight: 600; line-height: 1.3; letter-spacing: -0.01em; }
h1{ font-size: 1.5rem; }
h2{ font-size: 1.0625rem; }
h3{ font-size: 0.9375rem; }
p{ margin: 0 0 0.6em; }
a{ color: var(--primary); text-decoration: none; }
a:hover{ text-decoration: underline; }
img, svg, video{ display: block; max-width: 100%; }
button, input, select, textarea{ font: inherit; color: inherit; }
[hidden]{ display: none !important; }

.wrap{ width: 100%; max-width: 1360px; margin: 0 auto; padding: 0 24px; }
.mono{ font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.dim{ color: var(--text-2); }
.faint{ color: var(--text-muted); }
.tiny{ font-size: 0.75rem; }
.small{ font-size: 0.8125rem; }
.nowrap{ white-space: nowrap; }
.center{ text-align: center; }
.right{ text-align: right; }
.grow{ flex: 1; }
.stack{ display: grid; gap: 12px; }
.row{ display: flex; align-items: center; gap: 8px; }
.row.wrap-row{ flex-wrap: wrap; }
.spread{ display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.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;
}

/* ---------------------------------------------- app shell */

/* A left rail on a desktop, a top bar on a phone. Same markup either way, so
   the pages and the tests do not have to know which one they are in. */
.appbar{
  position: fixed; inset: 0 auto 0 0; z-index: 60;
  width: var(--sidebar);
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
}
.appbar .wrap{
  max-width: none; padding: 0;
  display: flex; flex-direction: column; height: 100%;
}

.brand{
  display: flex; align-items: center; gap: 10px;
  padding: 16px 18px;
  color: var(--text); text-decoration: none;
  border-bottom: 1px solid var(--border);
}
.brand:hover{ text-decoration: none; }
.brand .mark{
  width: 30px; height: 30px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  background: var(--primary); color: #fff;
}
.brand .mark svg{ width: 17px; height: 17px; }
.brand .name{ display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.brand .name b{ font-size: 0.9375rem; font-weight: 600; letter-spacing: -0.01em; }
.brand .name span{
  font-size: 0.6875rem; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.appnav{ display: flex; flex-direction: column; gap: 1px; padding: 10px; flex: 1; }
.appnav a{
  display: block; padding: 8px 11px; border-radius: var(--radius-sm);
  color: var(--text-2); font-size: 0.875rem; font-weight: 500; text-decoration: none;
}
.appnav a:hover{ background: var(--surface-3); color: var(--text); text-decoration: none; }
.appnav a[aria-current="page"]{ background: var(--primary-soft); color: var(--primary); font-weight: 600; }

.whoami{
  margin-top: auto; display: flex; align-items: center; gap: 9px;
  padding: 12px; border-top: 1px solid var(--border);
}
.avatar{
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center;
  background: var(--surface-3); color: var(--text-2);
  font-size: 0.6875rem; font-weight: 600;
}
.whoami .who{ min-width: 0; flex: 1; line-height: 1.25; }
.whoami .who b{ display: block; font-size: 0.8125rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.whoami .who span{ display: block; font-size: 0.6875rem; color: var(--text-muted); }

.nav-toggle{
  display: none;
  background: none; border: 1px solid var(--border-strong);
  color: var(--text-2); width: 34px; height: 32px; border-radius: var(--radius-sm); cursor: pointer;
}

/* Only the signed-in pages sit beside the rail. The sign-in screen is its own
   full-width layout and has no rail to make room for.

   width:auto matters: these <main> elements also carry .wrap, whose width:100%
   would otherwise be measured against the full page and then pushed across by
   the margin, making every screen exactly one sidebar too wide and scrolling
   sideways. Letting the width resolve from the remaining space fixes it. */
main:not(.auth-main){
  margin-left: var(--sidebar);
  width: auto;
  padding: 22px 24px 60px;
}

@media (max-width: 900px){
  .appbar{
    inset: 0 0 auto 0; width: auto; height: var(--topbar);
    border-right: 0; border-bottom: 1px solid var(--border);
  }
  .appbar .wrap{ flex-direction: row; align-items: center; padding: 0 16px; }
  .brand{ border-bottom: 0; padding: 0; flex: 1; }
  .nav-toggle{ display: grid; place-items: center; }
  .appnav{
    position: fixed; inset: var(--topbar) 0 auto 0;
    flex-direction: column; padding: 8px 16px 14px;
    background: var(--surface); border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-md);
  }
  .appnav:not(.open){ display: none; }
  .appnav a{ padding: 11px; }
  .whoami{ margin: 4px 0 0; border-top: 1px solid var(--border); }
  main:not(.auth-main){ margin-left: 0; padding-top: calc(var(--topbar) + 18px); }
}

/* ---------------------------------------------- page furniture */

.page-head{ margin-bottom: 18px; }
.page-head .eyebrow{
  display: block; margin-bottom: 4px;
  font-size: 0.6875rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-muted); font-weight: 600;
}
.page-head p{ color: var(--text-2); max-width: 74ch; margin: 5px 0 0; }

.card{
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px;
}
.card.tight{ padding: 12px; }
.card.flush{ padding: 0; overflow: hidden; }
.card-head{
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; margin-bottom: 13px;
}
.card-head h2, .card-head h3{ margin: 0; }
.card-head .sub{ font-size: 0.8125rem; color: var(--text-muted); margin-top: 1px; }

.grid{ display: grid; gap: 12px; }
.grid.two{ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid.three{ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid.four{ grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.grid.stats{ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }

/* ---------------------------------------------- stat tiles */

.stat{
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 13px 14px;
}
.stat .k{
  font-size: 0.6875rem; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-muted); font-weight: 600;
}
.stat .v{
  font-size: 1.5rem; font-weight: 600; letter-spacing: -0.02em;
  line-height: 1.2; margin-top: 4px; font-variant-numeric: tabular-nums;
  color: var(--text);
}
.stat .n{ font-size: 0.75rem; color: var(--text-muted); margin-top: 2px; }
/* Tone is carried by the number, not by painting the whole tile. */
.stat.ok .v{ color: var(--ok); }
.stat.warn .v{ color: var(--warn); }
.stat.danger .v{ color: var(--danger); }
.stat.info .v{ color: var(--info); }
.stat.violet .v{ color: var(--violet); }

/* ---------------------------------------------- buttons */

.btn{
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 8px 14px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--text);
  font-size: 0.875rem; font-weight: 500; cursor: pointer; text-decoration: none;
  transition: background 0.12s, border-color 0.12s;
  white-space: nowrap;
}
.btn:hover{ background: var(--surface-3); text-decoration: none; }
.btn:disabled, .btn[aria-disabled="true"]{ opacity: 0.5; cursor: not-allowed; }
.btn:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, button:focus-visible{
  outline: 2px solid var(--primary); outline-offset: 1px;
}
.btn.primary{
  background: var(--primary); border-color: var(--primary); color: #fff;
}
.btn.primary:hover{ background: var(--primary-dark); border-color: var(--primary-dark); }
.btn.ghost{ background: transparent; border-color: transparent; color: var(--text-2); }
.btn.ghost:hover{ background: var(--surface-3); color: var(--text); }
.btn.danger{ background: var(--surface); border-color: var(--danger-line); color: var(--danger); }
.btn.danger:hover{ background: var(--danger-soft); }
.btn.sm{ padding: 5px 10px; font-size: 0.8125rem; }
.btn.lg{ padding: 11px 18px; font-size: 0.9375rem; }
.btn.block{ width: 100%; }
.btn .spin{
  width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent;
  animation: spin 0.7s linear infinite;
}
@keyframes spin{ to{ transform: rotate(360deg); } }
.btn-row{ display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------------------------------------------- forms */

.field{ display: grid; gap: 5px; }
.field > label, .lbl{
  font-size: 0.75rem; font-weight: 600; color: var(--text-2);
}
.field .hint{ font-size: 0.75rem; color: var(--text-muted); }
input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="date"], input[type="time"], input[type="search"], input[type="tel"], select, textarea{
  width: 100%; padding: 8px 10px;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); color: var(--text);
  transition: border-color 0.12s, box-shadow 0.12s;
}
input:focus, select:focus, textarea:focus{
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}
input::placeholder, textarea::placeholder{ color: var(--text-muted); }
input:disabled, select:disabled{ background: var(--surface-3); opacity: 0.7; cursor: not-allowed; }
select{ cursor: pointer; }
textarea{ resize: vertical; min-height: 68px; }

.check{ display: flex; align-items: flex-start; gap: 9px; cursor: pointer; }
.check input{ width: 15px; height: 15px; margin-top: 2px; accent-color: var(--primary); cursor: pointer; flex-shrink: 0; }
.check span{ font-size: 0.875rem; }
.check .hint{ display: block; font-size: 0.75rem; color: var(--text-muted); }

.daypick{ display: flex; gap: 5px; flex-wrap: wrap; }
.daypick label{ cursor: pointer; }
.daypick input{ position: absolute; opacity: 0; pointer-events: none; }
.daypick span{
  display: grid; place-items: center; width: 38px; height: 31px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); font-size: 0.75rem; font-weight: 500; color: var(--text-2);
}
.daypick input:checked + span{ background: var(--primary-soft); border-color: var(--primary-line); color: var(--primary); font-weight: 600; }
.daypick input:focus-visible + span{ outline: 2px solid var(--primary); outline-offset: 1px; }

.filters{
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  align-items: end;
}

/* ---------------------------------------------- badges */

.badge{
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: 3px;
  font-size: 0.75rem; font-weight: 500; white-space: nowrap;
  background: var(--surface-3); color: var(--text-2);
  border: 1px solid var(--border);
}
.badge.ok{ background: var(--ok-soft); color: var(--ok); border-color: var(--ok-line); }
.badge.warn{ background: var(--warn-soft); color: var(--warn); border-color: var(--warn-line); }
.badge.danger{ background: var(--danger-soft); color: var(--danger); border-color: var(--danger-line); }
.badge.info{ background: var(--info-soft); color: var(--info); border-color: var(--info-line); }
.badge.violet{ background: var(--violet-soft); color: var(--violet); border-color: var(--violet-line); }
.badge .dot{ width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge.live .dot{ animation: pulse 1.8s ease-in-out infinite; }
@keyframes pulse{ 0%,100%{ opacity: 1; } 50%{ opacity: 0.3; } }

/* ---------------------------------------------- tables */

.table-scroll{ overflow-x: auto; }
table{ width: 100%; border-collapse: collapse; font-size: 0.8125rem; }
thead th{
  position: sticky; top: 0; z-index: 2;
  background: var(--surface-2);
  padding: 9px 12px; text-align: left; white-space: nowrap;
  font-size: 0.6875rem; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-muted); font-weight: 600;
  border-bottom: 1px solid var(--border);
}
tbody td{ padding: 9px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tbody tr:last-child td{ border-bottom: 0; }
tbody tr:hover{ background: var(--surface-2); }
td.num, th.num{ text-align: right; font-variant-numeric: tabular-nums; }
.table-empty{ padding: 36px 20px; text-align: center; color: var(--text-muted); }

.person{ display: flex; align-items: center; gap: 9px; min-width: 0; }
.person .avatar{ width: 28px; height: 28px; font-size: 0.6875rem; }
.person .who{ min-width: 0; }
.person .who b{ display: block; font-weight: 600; font-size: 0.8125rem; }
.person .who span{ display: block; font-size: 0.6875rem; color: var(--text-muted); }

.thumb{
  width: 32px; height: 32px; border-radius: var(--radius-sm); object-fit: cover;
  border: 1px solid var(--border); background: var(--surface-3); cursor: zoom-in;
}

/* ---------------------------------------------- tabs */

.tabs{
  display: flex; gap: 2px; overflow-x: auto;
  border-bottom: 1px solid var(--border); margin-bottom: 16px;
}
.tabs button{
  padding: 9px 14px; background: none; border: 0; cursor: pointer;
  color: var(--text-2); font-size: 0.875rem; font-weight: 500; white-space: nowrap;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tabs button:hover{ color: var(--text); }
.tabs button[aria-selected="true"]{ color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }

/* ---------------------------------------------- alerts */

.alert{
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 12px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-2);
  font-size: 0.8125rem; color: var(--text-2);
  /* Messages that have to give instructions need to be able to number them.
     Existing single-line messages are unaffected. */
  white-space: pre-line;
}
.alert .ico{ flex-shrink: 0; width: 16px; height: 16px; margin-top: 1px; }
.alert.ok{ background: var(--ok-soft); border-color: var(--ok-line); color: #0b6b4a; }
.alert.warn{ background: var(--warn-soft); border-color: var(--warn-line); color: #8a5800; }
.alert.danger{ background: var(--danger-soft); border-color: var(--danger-line); color: #a32b2a; }
.alert.info{ background: var(--info-soft); border-color: var(--info-line); color: #14509f; }
.alert b{ color: inherit; font-weight: 600; }

/* ---------------------------------------------- toasts */

.toasts{
  position: fixed; z-index: 1000; right: 16px; bottom: 16px;
  display: grid; gap: 8px; max-width: min(380px, calc(100vw - 32px));
}
.toast{
  padding: 10px 13px; border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-lg); font-size: 0.8125rem;
  border-left: 3px solid var(--text-muted);
  animation: toast-in 0.16s ease-out;
}
.toast.ok{ border-left-color: var(--ok); }
.toast.danger{ border-left-color: var(--danger); }
.toast.info{ border-left-color: var(--primary); }
@keyframes toast-in{ from{ opacity: 0; transform: translateY(6px); } }

/* ---------------------------------------------- modal */

.modal-back{
  position: fixed; inset: 0; z-index: 900;
  display: grid; place-items: center; padding: 18px;
  background: rgba(16,24,40,0.45);
  animation: fade 0.14s ease-out;
}
@keyframes fade{ from{ opacity: 0; } }
.modal{
  width: 100%; max-width: 520px; max-height: calc(100vh - 40px); overflow-y: auto;
  background: var(--surface); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 18px;
}
.modal.wide{ max-width: 760px; }
.modal-head{ display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.modal-close{
  background: none; border: 0; color: var(--text-muted); cursor: pointer;
  font-size: 1.3rem; line-height: 1; padding: 0 5px; border-radius: var(--radius-sm);
}
.modal-close:hover{ background: var(--surface-3); color: var(--text); }
.modal-foot{ display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; flex-wrap: wrap; }

/* ---------------------------------------------- sign in */

.auth-shell{ min-height: 100vh; display: grid; grid-template-columns: 1.05fr 1fr; }
.auth-aside{
  padding: 44px; display: flex; flex-direction: column; justify-content: space-between;
  background: var(--surface); border-right: 1px solid var(--border);
}
.auth-main{ display: grid; place-items: center; padding: 34px 22px; background: var(--page); }
.auth-card{ width: 100%; max-width: 380px; }
.auth-points{ display: grid; gap: 18px; margin: 30px 0; }
.auth-point{ display: flex; gap: 12px; align-items: flex-start; }
.auth-point .ico{
  width: 32px; height: 32px; border-radius: var(--radius-sm); flex-shrink: 0;
  display: grid; place-items: center;
  background: var(--primary-soft); color: var(--primary);
}
.auth-point .ico svg{ width: 16px; height: 16px; }
.auth-point b{ display: block; font-size: 0.875rem; font-weight: 600; }
.auth-point span{ font-size: 0.8125rem; color: var(--text-2); }
@media (max-width: 880px){
  .auth-shell{ grid-template-columns: 1fr; }
  .auth-aside{ display: none; }
}

/* ---------------------------------------------- camera */

.scan-stage{
  position: relative; width: 100%; aspect-ratio: 4 / 3;
  border-radius: var(--radius); overflow: hidden;
  background: #1a1f26; border: 1px solid var(--border);
}
.scan-stage video, .scan-stage canvas.mirror{
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; transform: scaleX(-1);
}
.scan-stage .overlay{ position: absolute; inset: 0; pointer-events: none; }
.scan-ring{
  position: absolute; left: 50%; top: 47%; transform: translate(-50%, -50%);
  width: min(60%, 250px); aspect-ratio: 3 / 4;
  border: 2px dashed rgba(255,255,255,0.35); border-radius: 50%;
  transition: border-color 0.2s;
}
.scan-stage[data-state="detecting"] .scan-ring{ border-color: #f0b429; border-style: solid; }
.scan-stage[data-state="matched"] .scan-ring{ border-color: #2fbf85; border-style: solid; }
.scan-stage[data-state="failed"] .scan-ring{ border-color: #ef5f5e; border-style: solid; }
.scan-status{
  position: absolute; left: 10px; right: 10px; bottom: 10px;
  padding: 8px 11px; border-radius: var(--radius-sm);
  background: rgba(16,24,40,0.82); color: #fff;
  font-size: 0.8125rem; display: flex; align-items: center; gap: 8px;
}
.scan-status .dot{ width: 7px; height: 7px; border-radius: 50%; background: #79838f; flex-shrink: 0; }
.scan-stage[data-state="detecting"] .scan-status .dot{ background: #f0b429; animation: pulse 1.2s infinite; }
.scan-stage[data-state="matched"] .scan-status .dot{ background: #2fbf85; }
.scan-stage[data-state="failed"] .scan-status .dot{ background: #ef5f5e; }
.scan-placeholder{
  position: absolute; inset: 0; display: grid; place-items: center;
  text-align: center; padding: 22px; color: #c4ccd6; font-size: 0.8125rem;
}

.samples{ display: flex; gap: 8px; justify-content: center; margin-top: 12px; }
.samples .slot{
  width: 50px; height: 50px; border-radius: var(--radius-sm);
  border: 1px dashed var(--border-strong); background: var(--surface-3);
  display: grid; place-items: center; color: var(--text-muted); font-size: 0.6875rem;
  overflow: hidden;
}
.samples .slot.filled{ border-style: solid; border-color: var(--ok-line); }
.samples .slot img{ width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }

/* ---------------------------------------------- progress */

.meter{ height: 6px; border-radius: 3px; background: var(--surface-3); overflow: hidden; }
.meter > i{ display: block; height: 100%; border-radius: 3px; background: var(--primary); transition: width 0.3s ease; }
.meter.warn > i{ background: var(--warn); }
.meter.danger > i{ background: var(--danger); }

.ring{ position: relative; width: 128px; height: 128px; }
.ring svg{ width: 100%; height: 100%; transform: rotate(-90deg); }
.ring circle{ fill: none; stroke-width: 9; stroke-linecap: round; }
.ring .track{ stroke: var(--surface-3); }
.ring .fill{ stroke: var(--primary); transition: stroke-dashoffset 0.5s ease; }
.ring .mid{ position: absolute; inset: 0; display: grid; place-items: center; text-align: center; }
.ring .mid b{ display: block; font-size: 1.4rem; font-weight: 600; }
.ring .mid span{ display: block; font-size: 0.6875rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }

/* ---------------------------------------------- map */

.map{
  height: 300px; border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--border); background: var(--surface-3);
  /* Leaflet gives its panes and controls z-index values in the hundreds. With
     no stacking context of its own the map would paint those into the root
     layer, and the zoom buttons and tiles would show through any dialog
     opened over them. isolate keeps all of that inside the map. */
  position: relative; z-index: 0; isolation: isolate;
}
.map.tall{ height: 420px; }
.map.short{ height: 190px; }
.leaflet-container{ font-family: var(--font) !important; }
.leaflet-control-attribution{ font-size: 10px !important; }

/* ---------------------------------------------- charts */

.chart{ width: 100%; overflow-x: auto; }
.chart svg{ display: block; min-width: 460px; width: 100%; height: auto; }
.chart .grid-line{ stroke: var(--border); stroke-width: 1; }
.chart .axis-label{ fill: var(--text-muted); font-size: 10px; font-family: var(--font); }
.chart .bar{ transition: opacity 0.12s; }
.chart .bar:hover{ opacity: 0.82; }
.legend{ display: flex; gap: 14px; flex-wrap: wrap; font-size: 0.75rem; color: var(--text-2); margin-top: 10px; }
.legend i{ width: 10px; height: 10px; border-radius: 2px; display: inline-block; margin-right: 5px; vertical-align: -1px; }

/* ---------------------------------------------- misc */

.skeleton{
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-2) 37%, var(--surface-3) 63%);
  background-size: 400% 100%; animation: shimmer 1.4s ease infinite; min-height: 16px;
}
@keyframes shimmer{ 0%{ background-position: 100% 0; } 100%{ background-position: 0 0; } }

.empty{ text-align: center; padding: 40px 20px; color: var(--text-muted); }
.empty svg{ width: 34px; height: 34px; margin: 0 auto 10px; opacity: 0.4; }
.empty b{ display: block; color: var(--text-2); margin-bottom: 3px; font-size: 0.875rem; }

.kv{ display: grid; grid-template-columns: auto 1fr; gap: 7px 16px; font-size: 0.8125rem; align-items: baseline; }
.kv dt{ color: var(--text-muted); }
.kv dd{ margin: 0; text-align: right; font-variant-numeric: tabular-nums; }

.divider{ height: 1px; background: var(--border); margin: 14px 0; border: 0; }
.pill-row{ display: flex; gap: 6px; flex-wrap: wrap; }

.copybox{
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px dashed var(--border-strong);
  font-family: var(--font-mono); font-size: 0.9375rem;
}
.copybox code{ flex: 1; word-break: break-all; }

@media print{
  .appbar, .toasts, .btn, .tabs, .filters, .no-print{ display: none !important; }
  body{ background: #fff; }
  main:not(.auth-main){ margin-left: 0; padding: 0; }
  .card{ border-color: #ccc; box-shadow: none; break-inside: avoid; }
  thead th{ background: #f0f0f0; }
}
