/* Shared design for the tools and the scan pages. Extracted from a
   <style> block in base.html so the CSP can drop 'unsafe-inline' for
   stylesheets -- and so browsers cache it instead of re-reading it on
   every page. */
  /* Dark is the site; light is a choice, remembered in localStorage and put
     on <html> by theme.js before the first paint -- which is the only reason
     that one file is loaded from <head> instead of with the rest.

     No prefers-color-scheme here any more, on purpose. The system asks a
     different question ("how do you like your apps?"), and letting it decide
     meant half the people we hand a login to saw a page nobody chose. The
     button says which one this is; the answer sticks per browser. */
  :root {
    color-scheme:dark;
    --bg:#0f1214; --panel:#171b1f; --fg:#e8eaed; --muted:#98a1ac;
    --line:#262b31; --line-strong:#333a42;
    --accent:#14b8a6; --accent-fg:#06231f; --accent-soft:#12312e;
    --danger:#f0685a; --warn:#e3b341;
    --radius:12px; --shadow:0 1px 2px rgba(0,0,0,.4);
  }
  :root[data-theme="light"] {
    color-scheme:light;
    --bg:#f6f7f9; --panel:#fff; --fg:#14181d; --muted:#6b7480;
    --line:#e3e6ea; --line-strong:#cfd4da;
    --accent:#0d9488; --accent-fg:#fff; --accent-soft:#e6f4f2;
    --danger:#b42318; --warn:#9a6700;
    --shadow:0 1px 2px rgba(16,24,40,.06), 0 1px 3px rgba(16,24,40,.1);
  }
  /* Paper is white whatever the screen is doing. Browsers drop background
     colours when printing but keep the text colour, so a dark page prints as
     #e8eaed on white -- a receipt nobody can read. */
  @media print {
    :root {
      color-scheme:light;
      --bg:#fff; --panel:#fff; --fg:#000; --muted:#444;
      --line:#ddd; --line-strong:#bbb; --accent-soft:#eee; --shadow:none;
    }
  }
  * { box-sizing:border-box; }
  html { -webkit-text-size-adjust:100%; }
  body {
    margin:0; background:var(--bg); color:var(--fg);
    font:16px/1.55 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
    -webkit-font-smoothing:antialiased;
  }

  /* header ------------------------------------------------------------- */
  .top {
    background:var(--panel); border-bottom:1px solid var(--line);
    position:sticky; top:0; z-index:5;
  }
  .top-in {
    max-width:900px; margin:0 auto; padding:12px 16px;
    display:flex; align-items:center; gap:12px;
  }
  .brand {
    font-weight:700; letter-spacing:-.02em; font-size:1.05rem;
    color:var(--fg); text-decoration:none; display:flex; align-items:center; gap:8px;
  }
  .top .spacer { flex:1; }

  /* layout ------------------------------------------------------------- */
  main { max-width:900px; margin:0 auto; padding:24px 16px 64px; }
  .narrow { max-width:440px; }
  h1 { font-size:1.6rem; line-height:1.2; letter-spacing:-.02em; margin:0 0 6px; }
  h2 { font-size:1.05rem; letter-spacing:-.01em; margin:32px 0 12px; }
  p { margin:0 0 14px; }
  .lead { color:var(--muted); margin:0 0 24px; }
  .muted { color:var(--muted); font-size:.9rem; }
  a { color:var(--accent); }

  .card {
    background:var(--panel); border:1px solid var(--line);
    border-radius:var(--radius); padding:18px; box-shadow:var(--shadow);
    margin:0 0 16px;
  }

  /* forms -------------------------------------------------------------- */
  label { display:block; font-size:.82rem; font-weight:600; color:var(--muted);
          margin:0 0 6px; }
  input {
    width:100%; padding:11px 12px; font:inherit; font-size:16px; color:var(--fg);
    background:var(--bg); border:1px solid var(--line-strong);
    border-radius:9px; outline:none;
  }
  input:focus { border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); }
  input::placeholder { color:var(--muted); opacity:.7; }
  .field { margin:0 0 14px; }
  .row { display:flex; gap:10px; flex-wrap:wrap; }
  details > summary { cursor:pointer; margin-bottom:10px; }
  /* admin: folding sections and lot groups */
  .sec > summary { margin:32px 0 12px; }
  .sec > summary h2 { display:inline; margin:0; }
  .lot-grp { border-top:1px solid var(--line); padding-top:10px; margin-top:10px; }
  .lot-grp:first-of-type { border-top:0; margin-top:0; }
  .row > * { flex:1 1 180px; min-width:0; }

  button, .btn {
    display:inline-flex; align-items:center; justify-content:center; gap:6px;
    padding:11px 16px; font:inherit; font-size:.95rem; font-weight:600;
    border:1px solid transparent; border-radius:9px; cursor:pointer;
    background:var(--accent); color:var(--accent-fg); text-decoration:none;
    min-height:42px;
  }
  button:hover, .btn:hover { filter:brightness(1.06); }
  button:active { transform:translateY(1px); }
  .btn-wide { width:100%; }
  .btn-ghost { background:transparent; color:var(--fg); border-color:var(--line-strong); }
  .btn-danger { background:transparent; color:var(--danger); border-color:var(--line-strong); }
  .btn-sm { padding:7px 11px; min-height:34px; font-size:.85rem; }

  /* bits --------------------------------------------------------------- */
  [dir="rtl"] .brand { letter-spacing:0; }
  .brand { direction:ltr; unicode-bidi:isolate; }
  code, .mono { direction:ltr; unicode-bidi:isolate; font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace; }
  code { background:var(--accent-soft); color:var(--fg);
         padding:2px 6px; border-radius:5px; font-size:.9em; }
  .note { padding:11px 13px; border-radius:9px; font-size:.92rem; margin:0 0 16px; }
  .note-err { background:rgba(180,35,24,.1); color:var(--danger);
              border:1px solid rgba(180,35,24,.25); }
  /* The link a client scans is the printed prefix plus the token. The token is
     on screen, the prefix never changes, so nobody should be retyping either.
     The button is an icon until it is pressed, then it says so in words. */
  .tok { display:inline-flex; align-items:center; gap:6px; min-width:0; }
  .copy-btn {
    background:none; border:0; padding:0; min-height:34px; min-width:34px;
    color:var(--muted); font-size:.78rem; font-weight:700;
  }
  .copy-btn:hover { color:var(--fg); filter:none; }
  .copy-btn.copied { color:var(--accent); }
  .copy-btn.copied svg { display:none; }
  .copy-btn.copied::after { content:"copie1"; }

  .badge {
    display:inline-block; padding:3px 9px; border-radius:999px;
    font-size:.74rem; font-weight:700; letter-spacing:.03em; text-transform:uppercase;
  }
  .badge-on { background:var(--accent-soft); color:var(--accent); }
  .badge-off { background:var(--line); color:var(--muted); }

  table { width:100%; border-collapse:collapse; font-size:.93rem; }
  th { text-align:left; font-size:.76rem; text-transform:uppercase;
       letter-spacing:.04em; color:var(--muted); padding:0 10px 8px 0; }
  td { padding:11px 10px 11px 0; border-top:1px solid var(--line); }
  td:last-child, th:last-child { padding-right:0; text-align:right; }

  dialog {
    /* the print dialog lives inside a <td class="nowrap">, so without this it
       inherits nowrap and its paragraphs run off the side. Pre-dates the CSP
       work; the markup was the same when the rule was a style attribute. */
    white-space:normal;
    border:1px solid var(--line); border-radius:var(--radius); padding:20px;
    background:var(--panel); color:var(--fg); max-width:380px; width:calc(100% - 32px);
    box-shadow:0 10px 30px rgba(0,0,0,.25); text-align:left;
  }
  dialog::backdrop { background:rgba(0,0,0,.5); }
  dialog h3 { font-size:1.05rem; letter-spacing:-.01em; }

  .stack { display:flex; flex-direction:column; gap:10px; }
  .between { display:flex; align-items:center; justify-content:space-between; gap:12px; }
  .wrap { overflow-wrap:anywhere; }


  .flash { border-radius:var(--radius); padding:12px 14px; margin:0 0 16px;
           border:1px solid; font-size:.95rem; }
  .flash-ok  { color:var(--accent); border-color:var(--accent); background:var(--accent-soft); }
  .flash-err { color:var(--danger); border-color:var(--danger); }

/* Former style="" attributes. They had to become classes: a CSP
   nonce covers a <style> element but never a style attribute, so
   style-src cannot drop 'unsafe-inline' while any remain. */
  .brand-tld { color:var(--muted);font-weight:500; }
  .check { width:auto;min-height:0; }
  .color { padding:4px; height:42px; }
  .dialog-wide { max-width:520px; }
  .print-preview { display:block; width:100%; height:auto; border-radius:9px;
                   border:1px solid var(--line); background:#fff; }
  .check-row { display:flex;align-items:center;gap:9px;font-weight:500;text-transform:none;font-size:.92rem;margin:0 0 16px; }
  .d-inline { display:inline; }
  .fs-85 { font-size:.85rem; }
  .label-sm { font-size:.8rem;text-transform:uppercase;letter-spacing:.06em; }
  .m0 { margin:0; }
  .mb10 { margin:0 0 10px; }
  .mb14 { margin:0 0 14px; }
  .mb16 { margin:0 0 16px; }
  .mb18 { margin:0 0 18px; }
  .mb22 { margin:0 0 22px; }
  .mb4 { margin:0 0 4px; }
  .mb6 { margin:0 0 6px; }
  .mt10 { margin:10px 0 0; }
  .mt14 { margin:14px 0 0; }
  .mt16 { margin-top:16px; }
  .mt24 { margin-top:24px; }
  .no-grow { flex:0 0 auto; }
  .note-sm { margin:16px 0 0;font-size:.84rem; }
  .nowrap { white-space:nowrap; }
  .pad-center { text-align:center;padding:26px 18px; }
  .select { width:100%;padding:11px 12px;font:inherit;font-size:16px;color:var(--fg);background:var(--bg);border:1px solid var(--line-strong);border-radius:9px; }
  .spacer { height:6vh; }
  .token-big { font-size:2.3rem;font-weight:700;letter-spacing:.14em;margin-top:10px;word-break:break-all; }
  .token-sm { font-size:1.15rem;letter-spacing:.06em; }
  .wide-mt { width:100%;margin-top:14px; }
  /* The switch itself: a sun when you are in the dark and could go light,
     a moon when you are in the light. No label, so nothing to translate. */
  .theme-btn { width:34px; padding:0; font-size:1rem; line-height:1; }
  .theme-btn::after { content:"☀"; }
  :root[data-theme="light"] .theme-btn::after { content:"☾"; }

/* the Wi-Fi page a plaque points at */
.wifi-val { font-size:1.6rem; font-weight:700; margin-top:6px; word-break:break-all; }
.wifi-copy.copied::after { content:" ✓"; }

/* stamp card (fidelite.html) */
.fid-dots { display:flex; flex-wrap:wrap; gap:8px; justify-content:center; margin:18px 0 10px; }
.fid-dots span { width:26px; height:26px; border-radius:50%; border:2px solid var(--line-strong); }
.fid-dots span.on { background:var(--accent); border-color:var(--accent); }
.fid-msg { font-size:1.15rem; font-weight:700; }
#confetti { position:fixed; top:0; left:0; width:100vw; height:100vh; pointer-events:none; z-index:50; }

/* owner dashboard */
.fid-stats { display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin:14px 0; }
.fid-stat { background:var(--panel); border:1px solid var(--line); border-radius:var(--radius); padding:12px 14px; }
.fid-stat b { display:block; font-size:1.6rem; line-height:1.2; }
.fid-stat span { color:var(--muted); font-size:.85rem; }
.fid-chart { width:100%; height:auto; display:block; }
.fid-bar { fill:var(--accent); }
.fid-bar0 { fill:var(--line-strong); }
.fid-log { list-style:none; margin:0; padding:0; }
.fid-log li { display:flex; justify-content:space-between; gap:10px; padding:8px 0; border-bottom:1px solid var(--line); font-size:.92rem; }
.fid-pill { display:inline-block; padding:2px 9px; border-radius:99px; background:var(--accent-soft); color:var(--fg); font-size:.8rem; margin:2px 4px 2px 0; }
.fid-qr { width:150px; height:150px; image-rendering:pixelated; background:#fff; padding:6px; border-radius:8px; }
.fid-shop > summary { cursor:pointer; list-style:none; }
.fid-shop > summary::-webkit-details-marker { display:none; }
@media (min-width:600px) { .fid-stats { grid-template-columns:repeat(4,1fr); } }
.fid-axis { fill:var(--muted); font-size:9px; }
