:root{
  --bg:#f6f7f9; --panel:#fff; --ink:#15181d; --muted:#5c6672; --line:#dfe3e8;
  --accent:#b3261e; --accent-soft:#fdecea; --chip:#eef1f4; --chip-on:#15181d;
  --shadow:0 1px 2px rgba(0,0,0,.06),0 4px 12px rgba(0,0,0,.05);
  --score-hi:#1a7f37; --score-mid:#8a6100; --score-low:#bc4c00; --score-bad:#b3261e;
  --glow:rgba(179,38,30,.75); --glow0:rgba(179,38,30,0);
}
@media (prefers-color-scheme:dark){:root:not([data-theme=light]){
  --bg:#0f1115; --panel:#171a20; --ink:#e8eaed; --muted:#98a1ad; --line:#272c34;
  --accent:#ff6b5e; --accent-soft:#2a1614; --chip:#232830; --chip-on:#e8eaed;
  --shadow:0 1px 2px rgba(0,0,0,.4),0 4px 14px rgba(0,0,0,.3);
  --score-hi:#3fb950; --score-mid:#d29922; --score-low:#f0883e; --score-bad:#ff6b5e;
  --glow:rgba(255,107,94,.8); --glow0:rgba(255,107,94,0);
}}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);
  font:15px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
header{position:sticky;top:0;z-index:20;background:var(--panel);border-bottom:1px solid var(--line);box-shadow:var(--shadow)}
.wrap{max-width:1080px;margin:0 auto;padding:0 16px}
.hrow{display:flex;align-items:center;gap:10px;padding:12px 0;flex-wrap:wrap}
h1{font-size:19px;margin:0;font-weight:650;letter-spacing:-.01em}
h1 span{color:var(--accent)}
/* Patreon mark, sitting next to the title. Opens in a new tab. */
.patreon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:22px;height:22px;text-decoration:none;border-radius:6px;
  transition:transform .15s,box-shadow .15s}
.patreon svg{display:block;width:22px;height:22px}
.patreon:hover{transform:translateY(-1px);box-shadow:0 2px 6px rgba(255,95,73,.45)}
.patreon:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
@media (prefers-reduced-motion:reduce){.patreon{transition:none}
  .patreon:hover{transform:none}}
.count{color:var(--muted);font-size:13px;font-variant-numeric:tabular-nums}
/* Last-save stamp, far right of the header row. Filled in by app.js from
   the savedAt field api.php writes on every write. */
.saved{color:var(--muted);font-size:12px;white-space:nowrap;margin-left:auto}
.grow{flex:1}
input,select,button,textarea{font:inherit;color:inherit}
input[type=search],input[type=text],input[type=password],input[type=date],select,textarea{
  background:var(--bg);border:1px solid var(--line);border-radius:8px;padding:7px 10px}
button{background:var(--chip);border:1px solid var(--line);border-radius:8px;padding:7px 12px;cursor:pointer}
button:hover{border-color:var(--muted)}
button.primary{background:var(--accent);border-color:var(--accent);color:#fff}
button.on{background:var(--chip-on);color:var(--panel);border-color:var(--chip-on)}
button:disabled{opacity:.38;cursor:default}
button:disabled:hover{border-color:var(--line)}

/* search with clear affordance */
.searchwrap{position:relative;display:flex;align-items:center}
.searchwrap input{min-width:250px;padding-right:30px}
.searchwrap input::-webkit-search-cancel-button{display:none}
.clearx{position:absolute;right:4px;background:none;border:0;padding:2px 6px;font-size:17px;
  line-height:1;color:var(--muted);cursor:pointer;display:none;border-radius:6px}
.clearx:hover{color:var(--accent);background:var(--chip)}
.searchwrap.filled .clearx{display:block}
.caret{display:inline-block;margin-left:5px;font-size:10px;transition:transform .15s}
.caret.up{transform:rotate(180deg)}

.chip{background:var(--chip);border:1px solid transparent;border-radius:999px;
  padding:3px 10px;font-size:13px;cursor:pointer;user-select:none;white-space:nowrap}
.chip:hover{border-color:var(--muted)}
.chip.on{background:var(--chip-on);color:var(--panel)}
.chip .n{opacity:.55;font-size:11px;margin-left:4px;font-variant-numeric:tabular-nums}

/* ---- small header buttons ---- */
.btn-sm{font-size:10.5px;padding:3px 8px;border-radius:6px}

/* ---- period bar: always visible, never collapses ---- */
.periodbar{display:flex;gap:4px;align-items:center;flex-wrap:wrap;padding:0 0 9px}
.periodbar select{padding:1px 1px 1px 3px;font-size:10.5px;border-radius:5px}
.periodbar #fromMo,.periodbar #toMo{width:38px}
.periodbar #fromYr,.periodbar #toYr{width:54px}
.periodbar .sep{color:var(--muted);padding:0 2px;font-size:10.5px}
.periodbar .pair{display:flex;gap:2px}
.periodbar button{font-size:10.5px;padding:2px 7px;border-radius:6px}
.periodbar .spacer{width:22px}

/* ---- filter panel: everything here runs at roughly half scale ---- */
.filters{padding-bottom:7px;display:none}
.filters.open{display:block}
.fgroup{display:flex;gap:4px;align-items:flex-start;padding:3px 0;flex-wrap:wrap}
.flabel{font-size:9px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);
  min-width:46px;padding-top:4px;font-weight:700}
.periodbar .flabel{padding-top:0}
.filters button{font-size:10.5px;padding:2px 7px;border-radius:6px}
.filters .chip{padding:1px 7px;font-size:10.5px}
.filters .chip .n{font-size:9px;margin-left:3px}
.filters .count{font-size:10.5px;align-self:center}
.tagwall{display:flex;flex-wrap:wrap;gap:3px;flex:1}
.srcbtn{font-size:10.5px;padding:2px 9px;border-radius:6px;border:1px solid var(--line);
  background:var(--chip);cursor:pointer;font-weight:650}
.srcbtn .n{opacity:.55;font-weight:400;font-variant-numeric:tabular-nums;margin-left:3px}
.srcbtn.s-hi{color:var(--score-hi)}
.srcbtn.s-mid{color:var(--score-mid)}
.srcbtn.s-low{color:var(--score-low)}
.srcbtn.s-none{color:var(--score-bad)}
.srcbtn.on{color:var(--panel)}
.srcbtn.s-hi.on{background:var(--score-hi);border-color:var(--score-hi)}
.srcbtn.s-mid.on{background:var(--score-mid);border-color:var(--score-mid)}
.srcbtn.s-low.on{background:var(--score-low);border-color:var(--score-low)}
.srcbtn.s-none.on{background:var(--score-bad);border-color:var(--score-bad)}

main{max-width:1080px;margin:0 auto;padding:16px}
.updatenote{font-size:11.5px;color:var(--ink);margin:0 0 3px;padding-left:2px}
.updatenote:last-of-type{margin-bottom:10px}
.updatenote a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.updatenote a:hover{color:var(--accent)}
.card{background:var(--panel);border:1px solid var(--line);border-radius:10px;
  padding:12px 14px;margin-bottom:10px;box-shadow:var(--shadow)}
.datebar{display:flex;align-items:center;gap:22px}
.date{color:var(--accent);font-size:12px;font-weight:650;font-variant-numeric:tabular-nums;
  letter-spacing:.02em}
.head{margin:3px 0 6px;font-size:15.5px;line-height:1.42}
.note{color:var(--muted);font-size:13.5px;font-style:italic;margin:0 0 7px;
  border-left:2px solid var(--line);padding-left:9px}
/* links, tags and the edit control all share one row */
.meta{display:flex;gap:5px;flex-wrap:wrap;align-items:center}
.meta a{font-size:11.5px;color:var(--muted);text-decoration:none;background:var(--chip);
  padding:2px 8px;border-radius:6px;border:1px solid transparent}
.meta a:hover{color:var(--accent);border-color:var(--accent)}
.score{font-weight:700;margin-left:3px;font-variant-numeric:tabular-nums}
.s-hi{color:var(--score-hi)}
.s-mid{color:var(--score-mid)}
.s-low{color:var(--score-low)}
.s-bad{color:var(--score-bad)}
.meta .div{width:1px;align-self:stretch;background:var(--line);margin:1px 4px}
.tag{font-size:11.5px;background:var(--accent-soft);color:var(--accent);
  padding:2px 8px;border-radius:999px;cursor:pointer;border:1px solid transparent}
.tag:hover{border-color:var(--accent)}
.untagged{font-size:11.5px;color:var(--muted);font-style:italic}
.addtag{font-size:11.5px;border:1px dashed var(--line);border-radius:999px;padding:2px 9px;
  cursor:pointer;color:var(--muted);background:none}
/* left marker = best source score on the story */
.card{border-left:4px solid var(--score-bad)}
.card.b-hi{border-left-color:var(--score-hi)}
.card.b-mid{border-left-color:var(--score-mid)}
.card.b-low{border-left-color:var(--score-low)}
.card.b-none{border-left-color:var(--score-bad)}
.editonly{display:none}
body.editing .editonly{display:inline-flex}
/* Shown only when NOT editing. Edit is the way in; Lock is the way out. */
body.editing .viewonly{display:none}
mark{background:var(--accent-soft);color:inherit;border-radius:3px;padding:0 2px}
.empty{text-align:center;color:var(--muted);padding:60px 20px}

/* pager */
.pager{display:flex;gap:4px;justify-content:center;align-items:center;flex-wrap:wrap;
  padding:22px 0 40px}
.pager button{min-width:36px;padding:6px 10px;font-variant-numeric:tabular-nums}
.pager button.on{background:var(--accent);border-color:var(--accent);color:#fff}
.pager .gap{color:var(--muted);padding:0 3px}
.pagerinfo{width:100%;text-align:center;color:var(--muted);font-size:12.5px;padding-bottom:8px;
  font-variant-numeric:tabular-nums}

dialog{border:1px solid var(--line);border-radius:12px;background:var(--panel);color:var(--ink);
  padding:0;box-shadow:0 10px 40px rgba(0,0,0,.3);max-width:560px;width:92vw}
dialog::backdrop{background:rgba(0,0,0,.45)}
.dlg{padding:18px}
.dlg h3{margin:0 0 12px;font-size:16px}
.dlg label{display:block;font-size:12px;color:var(--muted);margin:10px 0 4px;font-weight:600}
.dlg input,.dlg textarea,.dlg select{width:100%}
.dlg textarea{min-height:64px;resize:vertical}
.dlgrow{display:flex;gap:8px;justify-content:flex-end;margin-top:16px}
.picker{display:flex;flex-wrap:wrap;gap:5px;max-height:230px;overflow:auto;padding:8px;
  border:1px solid var(--line);border-radius:8px;background:var(--bg)}
.status{font-size:12px;color:var(--muted);margin-right:auto;align-self:center}
.rowflex{display:flex;gap:6px}

/* stale-copy warning */
.staleBar{display:none;background:var(--accent);color:#fff;padding:8px 16px;font-size:13px;
  align-items:center;gap:12px;justify-content:center;flex-wrap:wrap}
.staleBar.show{display:flex}
.staleBar button{background:#fff;color:var(--accent);border:0;font-weight:650;
  padding:3px 12px;border-radius:6px;font-size:12px}
.staleBar b{font-weight:700}

/* tag manager rows: name · count · rename · remove */
.tagrow{display:inline-flex;align-items:center;gap:5px}
.tagrow .act{cursor:pointer;opacity:.45;font-style:normal;font-weight:700;
  padding:0 2px;border-radius:4px;line-height:1}
.tagrow .act:hover{opacity:1;background:var(--panel)}
.tagrow .rm:hover{color:var(--accent)}
.tagrow input.rename{width:9em;font-size:12.5px;padding:1px 6px;border-radius:6px;
  border:1px solid var(--accent);background:var(--panel)}
.hint{font-size:11.5px;color:var(--muted);margin-top:6px}

/* ---- Save button pulses while there are unsaved changes ---- */
@keyframes saveGlow {
  0%   { box-shadow: 0 0 0 0 var(--glow); }
  80%  { box-shadow: 0 0 0 16px var(--glow0); }
  100% { box-shadow: 0 0 0 0 var(--glow0); }
}
#saveBtn.dirty {
  animation: saveGlow 1.8s ease-out infinite;
  font-weight: 700;
  position: relative;
  z-index: 1;            /* ring paints over neighbouring buttons, not under */
}
@media (prefers-reduced-motion: reduce) {
  #saveBtn.dirty { animation: none; box-shadow: 0 0 0 4px var(--glow); }
}

/* Auto-save status, where the Save button used to be. Quiet when everything is
   written; only speaks up while saving or when something went wrong. */
.savestate{font-size:12px;letter-spacing:.02em;padding:3px 8px;border-radius:6px;
  white-space:nowrap;opacity:.75}
.savestate.busy{opacity:1}
.savestate.ok{color:#2e7d4f;opacity:1}
.savestate.bad{color:#fff;background:#b3202e;opacity:1;font-weight:700}
