:root{
  color-scheme: light dark;
  --bg:#F3F5F2;
  --surface:#FFFFFF;
  --surface-2:#EAEFEA;
  --ink:#1C2422;
  --ink-soft:#5C6864;
  --ink-faint:#93A19B;
  --line:#DCE3DE;
  --accent:#3D5A80;
  --accent-ink:#FFFFFF;
  --danger:#A83E3E;
  --prio-urgent:#B42318;
  --prio-high:#C4540F;
  --prio-medium:#9A7200;
  --prio-low:#4F7A63;
  /* Deadline chip stages (#106). Borders + tint + words, never hue alone: --due-soon is an olive-lime and
     --due-now a crimson, apart from the gold --prio-medium, orange --prio-high and red --prio-urgent. */
  --due-soon:#4F5A00;
  --due-now:#AB0F46;
  --proj-sat:58%;
  --proj-light:40%;
  /* Type scale (Q17a): exactly five sizes. See docs/4-systems/styling.md#visual-system */
  --text-sm:.8rem;
  --text-body:.95rem;
  --text-h:1.15rem;
  --text-q:1.5rem;
  --text-title:2.1rem;
  /* Corners (Q17a): exactly three radii. Circles (dots, icon buttons) stay 50% — a shape, not a step. */
  --r-pill:999px;
  --r-control:10px;
  --r-card:18px;
  --shadow:0 1px 2px rgba(28,36,34,.06), 0 6px 20px rgba(28,36,34,.07);
  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:#14181A;
    --surface:#1B2124;
    --surface-2:#20282A;
    --ink:#EAEFEC;
    --ink-soft:#AEBAB5;
    --ink-faint:#6C7975;
    --line:#2B3336;
    --accent:#8FADD6;
    --accent-ink:#10161A;
    --danger:#DD8686;
    --prio-urgent:#F08A80;
    --prio-high:#F0A060;
    --prio-medium:#E6C35C;
    --prio-low:#8FB79E;
    --due-soon:#D9E66B;
    --due-now:#FF88B0;
    --proj-sat:55%;
    --proj-light:68%;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 6px 20px rgba(0,0,0,.35);
  }
}
:root[data-theme="dark"]{
  --bg:#14181A;
  --surface:#1B2124;
  --surface-2:#20282A;
  --ink:#EAEFEC;
  --ink-soft:#AEBAB5;
  --ink-faint:#6C7975;
  --line:#2B3336;
  --accent:#8FADD6;
  --accent-ink:#10161A;
  --danger:#DD8686;
  --prio-urgent:#F08A80;
  --prio-high:#F0A060;
  --prio-medium:#E6C35C;
  --prio-low:#8FB79E;
  --due-soon:#D9E66B;
  --due-now:#FF88B0;
  --proj-sat:55%;
  --proj-light:68%;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 6px 20px rgba(0,0,0,.35);
}
*{box-sizing:border-box;}
html,body{height:100%;}
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:'IBM Plex Sans', system-ui, -apple-system, sans-serif;
  font-size:var(--text-body);
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;}
[hidden]{display:none!important;}
h1,h2,h3,h4{font-family:'Fraunces', Georgia, serif; margin:0; text-wrap:balance; font-weight:600;}
/* Section headings (Q18a): Fraunces italic, sentence case, no letter-spacing or uppercase. h2 is the
   default "section heading" size/style; .focus-q/.focus-title (the two big Fraunces moments) and
   h3 (project names, upright) override it below. */
h2{font-size:var(--text-h); font-style:italic;}
h3{font-size:var(--text-h); font-style:normal;}
h4{font-size:var(--text-body); font-style:italic; font-weight:600; color:var(--ink-soft);}
p{margin:0;}
button,input,select{font:inherit; color:inherit;}
button{cursor:pointer;}
a{color:inherit;}
*:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
@media (prefers-reduced-motion: reduce){
  *{transition:none!important; scroll-behavior:auto!important;}
}

.wrap{max-width:760px; margin:0 auto; padding:0 16px 64px;}

.topbar{
  position:sticky; top:env(safe-area-inset-top,0px);
  z-index:10;
  background:var(--bg);
  padding-block:16px 12px;
  display:flex; flex-wrap:wrap; gap:10px 16px; align-items:center; justify-content:space-between;
  border-bottom:1px solid var(--line);
  margin-bottom:18px;
}
.brand{display:flex; align-items:center; gap:8px;}
/* The brand mark is a hand-drawn SVG compass (js/icons.js ICON_COMPASS, inlined statically here and
   in settings.html — see docs/4-systems/styling.md#icons), in the accent colour. */
.brand-mark{display:inline-flex; color:var(--accent);}
.brand-mark svg{width:22px; height:22px;}
.brand h1{font-size:var(--text-h); font-style:normal; font-weight:600; letter-spacing:-.01em;}
.capture-form{display:flex; gap:8px; flex:1 1 260px; min-width:0;}
#capture-input{
  flex:1; min-width:0; padding:9px 12px;
  border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink);
}
#capture-input::placeholder{color:var(--ink-faint);}
.capture-form button{
  padding:9px 16px; border:none; border-radius:var(--r-control);
  background:var(--accent); color:var(--accent-ink); font-weight:600; white-space:nowrap;
}

/* The topbar sync icon, settings icon and Projects drawer toggle (index.html, outside #app). See
   docs/4-systems/styling.md#sync-button and #icons */
.icon-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:32px; height:32px; padding:0; border:none; background:none; border-radius:50%;
  color:var(--ink-soft);
}
.icon-btn:hover{color:var(--ink); background:var(--surface-2);}
.icon-btn:disabled{cursor:default; opacity:.6;}
.icon-btn.is-syncing svg{animation:spin 1s linear infinite;}
@keyframes spin{to{transform:rotate(360deg);}}
@media (prefers-reduced-motion: reduce){
  .icon-btn.is-syncing svg{animation:none;}
}
.topbar-tools{display:flex; align-items:center; gap:12px;}
/* on a phone the brand and the tools share the first row and capture gets the full second row,
   instead of the tools wrapping onto a row of their own */
@media (max-width:699px){.capture-form{order:1; flex-basis:100%;}}
.projects-toggle{white-space:nowrap;}
@media (min-width:1100px){.projects-toggle{display:none;}}

/* One raised card (Q5): the focus card is the only surface with a background, radius and shadow.
   .inbox-card, .project-card and settings.html's .settings-section below override this back to flat, each with its own thin top rule. */
.card{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card);
  box-shadow:var(--shadow); padding:20px; margin-bottom:16px;
}
@media (min-width:700px){
  .card{padding:28px;}
}

.focus-empty .focus-q{font-size:var(--text-q); font-style:normal; margin-bottom:6px;}
.muted{color:var(--ink-soft);}
.muted.small{font-size:var(--text-sm);}
.focus-empty .muted{margin-bottom:16px; display:block;}
.energy-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin-bottom:12px;}
@media (max-width:560px){.energy-grid{grid-template-columns:1fr;}}
.energy-btn{
  border:1px solid var(--line); background:var(--surface-2); border-radius:var(--r-control);
  padding:14px 12px; text-align:left; display:flex; flex-direction:column; gap:4px;
  border-top:3px solid var(--chip-color);
}
.energy-btn:hover{background:var(--surface);}
.energy-label{font-weight:600;}
.energy-desc{font-size:var(--text-sm); color:var(--ink-soft);}
.link-btn{background:none; border:none; color:var(--accent); font-weight:600; padding:4px 0;}
.link-btn.small{font-size:var(--text-sm); padding:2px 0;}
.link-btn:hover{text-decoration:underline;}

.focus-tags{display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-bottom:10px;}
.chip{
  display:inline-flex; align-items:center; font-size:var(--text-sm); font-weight:600;
  padding:4px 10px; border-radius:var(--r-pill); background:var(--surface-2); color:var(--ink-soft);
  border:1px solid var(--line);
}
/* A project's own chip/pill is neutral (Q4b — its colour is identity only: its dot and its card
   edge), carrying a small colour dot (.proj-dot) rather than a colour tint. */
.chip.proj-chip{background:var(--surface-2); color:var(--ink);}
button.chip.proj-chip:hover{background:var(--line);}
.proj-dot{display:inline-block; width:8px; height:8px; border-radius:50%; background:var(--dot); margin-right:6px; flex:none;}
.chip.deadline-chip{font-variant-numeric:tabular-nums;}
.chip.deadline-chip svg{flex:none; margin-right:4px;}
/* Stage colours (#106): task deadline chips only, same size as every other chip. White is the
   neutral chip; yellow and red add a tint and a border so they differ from the borderless priority
   chips even where a hue is close. A done task or a project deadline gets no stage class. */
.chip.deadline-chip.due-white{background:var(--surface-2); color:var(--ink-soft);}
.chip.deadline-chip.due-yellow{background:color-mix(in srgb, var(--due-soon) 18%, transparent); color:var(--due-soon); border-color:color-mix(in srgb, var(--due-soon) 60%, transparent); font-weight:700;}
.chip.deadline-chip.due-red{background:color-mix(in srgb, var(--due-now) 18%, transparent); color:var(--due-now); border-color:color-mix(in srgb, var(--due-now) 60%, transparent); font-weight:700;}
.chip.gh-chip{border-color:transparent; background:var(--surface-2); color:var(--ink-soft); text-decoration:none;}
.chip.gh-chip.small{font-size:var(--text-sm); padding:3px 8px;}
.chip.gh-chip:hover{color:var(--accent);}
/* Label colours keep their GitHub hue but muted toward the app's palette (Q4b) — the raw colour
   value handed to --chip-color is already mixed toward --ink-soft in js/render.js's mutedChip(),
   so this rule just reads it back; text is pulled further toward ink so a light colour (e.g.
   yellow) stays readable. */
.chip.cat-chip{border-color:transparent; background:color-mix(in srgb, var(--chip-color) 18%, transparent); color:color-mix(in srgb, var(--chip-color) 55%, var(--ink)); font-weight:700;}
.chip.cat-chip.claude-chip{background:var(--surface-2); color:var(--ink-soft);} /* "Claude created" (#104): a neutral label chip, not a tinted category */
.chip.priority-chip{border-color:transparent; background:color-mix(in srgb, var(--chip-color) 18%, transparent); color:var(--chip-color); font-weight:700; cursor:pointer;}
.chip.priority-chip.small{font-size:var(--text-sm); padding:3px 8px;}
.chip.priority-chip:disabled{opacity:.5; cursor:default;}
.focus-title{font-size:var(--text-title); font-style:normal; line-height:1.15; margin-bottom:16px;}
.focus-actions{display:flex; flex-wrap:wrap; gap:10px;}
/* focus picker: project pills, then label cards that reuse .energy-btn; two across on a phone */
.focus-scope{margin:-4px 0 14px;}
/* focus picker pills for labels match their chip's colour: tinted in it; chosen = a ring. Project
   pills (no --chip-color set) stay a plain .filter-pill with a .proj-dot instead. */
.filter-pill.tint-pill{border-color:transparent; background:color-mix(in srgb, var(--chip-color) 18%, transparent); color:color-mix(in srgb, var(--chip-color) 55%, var(--ink));}
.filter-pill.tint-pill.active{background:color-mix(in srgb, var(--chip-color) 32%, transparent); color:var(--ink); box-shadow:inset 0 0 0 2px var(--chip-color);}
.filter-pill.focus-more-pill{background:none; border-style:dashed; color:var(--ink-faint);}
@media (max-width:560px){.energy-grid.focus-grid{grid-template-columns:1fr 1fr;}}
.focus-grid .energy-label{overflow-wrap:anywhere;}
.focus-links{display:flex; flex-wrap:wrap; gap:4px 18px;}
.energy-btn.selected{background:color-mix(in srgb, var(--chip-color) 16%, var(--surface-2)); box-shadow:inset 0 0 0 2px var(--chip-color);}
.sort-head{display:flex; flex-wrap:wrap; align-items:center; justify-content:flex-start; gap:4px 10px; margin-bottom:10px;}
.sort-title{font-size:var(--text-h); font-style:normal; margin:4px 0 14px;}
.sort-q{margin:0 0 8px;}
.sort-kinds{margin-bottom:14px;}
.sort-labels{margin-bottom:12px;}
.sort-new{width:100%; padding:9px 12px; margin-bottom:14px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink);}
.focus-surprise{display:flex; flex-wrap:wrap; align-items:center; gap:8px 14px; margin-top:18px; padding-top:16px; border-top:1px solid var(--line);}
.focus-empty .focus-surprise .muted{margin:0;} /* beats .focus-empty .muted's paragraph spacing */
.btn{border-radius:var(--r-control); padding:10px 18px; font-weight:600; border:1px solid var(--line); background:var(--surface-2);}
.btn.primary{background:var(--accent); color:var(--accent-ink); border-color:transparent;}
.btn.ghost:hover{background:var(--surface-2);}
.btn-text{background:none; border:none; padding:3px 7px; font-size:var(--text-sm); font-weight:600; color:var(--ink-faint); border-radius:var(--r-control);}
.btn-text:hover{background:var(--surface-2); color:var(--ink-soft);}
.btn-text.danger{color:var(--danger);}
.remove-confirm{display:flex; align-items:center; gap:4px; font-size:var(--text-sm); color:var(--ink-soft); flex-wrap:wrap;}

/* Flat sections (Q5): the Unsorted card and every project card lose the raised-card look and get a
   thin top rule instead — a project's is its 3px colour edge (identity, Q4), which doubles as that
   rule. */
.inbox-card, .project-card, .settings-section{
  background:none; box-shadow:none; border-radius:0; border-left:none; border-right:none;
  border-bottom:none; padding:20px 0;
}
.inbox-card{border-top:1px solid var(--line); padding:14px 0;}
.settings-section{border-top:1px solid var(--line);}
/* the topbar's own bottom rule already separates the first section */
.settings-section:first-of-type{border-top:none; padding-top:0;}
.section-toggle{
  width:100%; text-align:left; background:none; border:none; padding:6px 0;
  display:flex; align-items:center; gap:8px;
  font-family:'Fraunces', Georgia, serif; font-style:italic; font-weight:600; font-size:var(--text-h);
}
.section-toggle.small{width:auto; font-family:inherit; font-style:normal; font-size:var(--text-sm); color:var(--ink-soft); margin:6px 0; font-weight:600;}
.section-toggle .count{color:var(--ink-faint); font-weight:500; font-size:var(--text-sm);}
.section-toggle .chev{margin-left:auto; color:var(--ink-faint);}
.unsorted-body{margin-top:12px;}
.unsorted-delete{margin-left:auto;} /* sits at the far right of the head row, away from the flow buttons */
.unsorted-delete:hover{color:var(--danger);}
.task-edit-github{flex:1 1 100%; display:flex; flex-wrap:wrap; align-items:center; gap:4px 12px; font-size:var(--text-sm); color:var(--ink-faint);}
.task-edit-form .task-edit-github button[type="button"]{background:none; color:var(--accent); padding:2px 0; font-size:var(--text-sm);}
.mini-x{border:none; background:var(--surface-2); color:var(--ink-soft); width:22px; height:22px; border-radius:50%; line-height:1;}

.filter-pills{display:flex; flex-wrap:wrap; gap:6px;}
.filter-pill{
  border:1px solid var(--line); background:var(--surface); border-radius:999px;
  padding:6px 13px; font-size:var(--text-sm); font-weight:600; color:var(--ink-soft);
}
.filter-pill.active{background:var(--accent); color:var(--accent-ink); border-color:transparent;}
.project-search{
  flex:1 1 160px; min-width:0; padding:7px 12px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink);
}
.project-sort-select{
  padding:7px 10px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink); font-size:var(--text-sm);
}

/* Category-colour group labels: a section heading, not an uppercase micro-label (Q18a). */
.cat-color-group-label{font-size:var(--text-sm); font-family:'Fraunces', Georgia, serif; font-style:italic; font-weight:600; color:var(--ink-soft); margin:16px 0 8px;}
.cat-color-group-label:first-child{margin-top:0;}
.cat-color-list{display:flex; flex-direction:column; gap:8px;}
.cat-color-row{display:flex; align-items:center; justify-content:space-between; gap:12px; border-top:1px solid var(--line); padding-top:8px;}
.cat-color-row:first-child{border-top:none; padding-top:0;}
.cat-color-input{width:40px; height:32px; padding:2px; border:1px solid var(--line); border-radius:var(--r-control); background:none; cursor:pointer;}
.cat-color-row-actions{display:flex; align-items:center; gap:6px;}
.chip.chip-btn{cursor:pointer;}
.chip.chip-btn:hover{filter:brightness(1.08);}
.chip.cat-chip.chip-placeholder{background:var(--surface-2); color:var(--ink-faint); border:1px dashed var(--line); font-weight:600;}
.project-cat-edit{display:inline-flex; align-items:center; gap:4px;}
.project-cat-edit select{
  padding:4px 9px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink); font-size:var(--text-sm);
}
/* Minimising is back (PR 6, 2026-09-27): js/render.js leaves the toggle and "Collapse all" out of
   the markup itself in the "One" view, so there's nothing here to hide by width or view. */
.project-card.is-collapsed{padding-bottom:16px;}
.project-card.is-collapsed .progress-track{margin-bottom:0;}
/* The "All"/"One" switch: two pills right under the sidebar/drawer title. */
.view-switch{display:flex; gap:6px;}
/* the labels never break mid-label ("New / project") in the 270px sidebar */
.view-switch .filter-pill{white-space:nowrap;}
/* Minimised projects gather below the full-size tiles as their own quiet group (#82: a minimised
   tile left in the tile grid would sit beside a full-height one and reopen the gap). */
.minimised-projects{margin-top:24px;}

.projects-grid{display:grid; grid-template-columns:1fr; gap:16px; margin-bottom:16px;}

/* The one project list: a fixed drawer below 1100px (opened from the topbar's Projects button),
   a flat sticky left column at and above it. See docs/4-systems/styling.md#project-sidebar */
.project-sidebar{
  position:fixed; top:0; left:0; z-index:30;
  width:min(320px, 85vw); height:100%; overflow-y:auto;
  display:flex; flex-direction:column; gap:10px;
  background:var(--surface); border-right:1px solid var(--line);
  padding:16px; padding-top:calc(16px + env(safe-area-inset-top, 0px)); padding-bottom:calc(16px + env(safe-area-inset-bottom, 0px));
  transform:translateX(-100%);
  /* hidden once slid away, so keyboard and screen-reader users can't land in a closed drawer */
  visibility:hidden;
  transition:transform .2s ease, visibility 0s linear .2s;
}
.project-sidebar.is-open{transform:translateX(0); visibility:visible; transition:transform .2s ease;}
.project-sidebar:focus{outline:none;}
.drawer-backdrop{
  position:fixed; inset:0; z-index:29;
  background:rgba(0,0,0,.4); opacity:0; pointer-events:none;
  transition:opacity .2s ease;
}
.drawer-backdrop.is-open{opacity:1; pointer-events:auto;}
@media (prefers-reduced-motion: reduce){
  .project-sidebar{transition:none;}
  .drawer-backdrop{transition:none;}
}
.main-col{min-width:0;}
/* "One" view, any width (PR 6, 2026-09-27): every card is still rendered into the same
   projects-grid the "All" tiles use, but only the selected one shows here; the rest are hidden
   outright rather than left tall and empty. See docs/6-decisions/Decisions.md. */
.view-one .project-card{display:none;}
.view-one .project-card.is-selected{display:block;}
@media (min-width:1100px){
  /* use the monitor (#64): the page widens, and the focus card's label cards spread across it */
  .wrap{max-width:1800px;}
  #app{display:grid; grid-template-columns:270px minmax(0,1fr); gap:28px; align-items:start;}
  /* "All" view, 2x2 tiles (Q26a, #82): every non-minimised project is its own tile, two columns,
     every tile the same height -- half the space below the sticky topbar (--topbar-h, set from
     js/app.js's updateTopbarHeightVar, since the topbar's real height varies with width and
     content), with a floor so a narrow-ish wide screen still gets a usable tile. grid-auto-rows
     applies that same height to every row, not just the first, so further projects continuing below
     stay level too. Minimised projects are left out of this grid by js/render.js and gather in
     .minimised-grid below instead, at their own natural height, two to a row. */
  .view-all .projects-grid{
    grid-template-columns:1fr 1fr;
    grid-auto-rows:max(320px, calc((100dvh - var(--topbar-h, 64px) - 16px) / 2));
    align-items:stretch;
  }
  .view-all .minimised-grid{grid-auto-rows:auto;}
  .view-all .project-card{
    display:flex; flex-direction:column; overflow:hidden;
    /* the fixed tile height means a card can't grow with its own content -- min-height:0 lets the
       flex child (.project-body) shrink below its content size so it, not the tile, scrolls */
    min-height:0;
    /* .card's own margin-bottom would otherwise stack on top of the grid gap between rows (#82) */
    margin-bottom:0;
  }
  /* the scrollable part of a full tile: header, badges, edit panel and progress bar stay put above
     it. A minimised tile has no body at all (js/render.js), so this never applies to one; the "One"
     view's single card isn't a fixed-height tile either, so it keeps its natural page scroll. */
  /* a rule marks where the tile ends, so rows cut off by a long list read as scrollable, not broken */
  .view-all .project-card:not(.is-collapsed) .project-body{flex:1 1 auto; min-height:0; overflow-y:auto; border-bottom:1px solid var(--line);}
  /* only the task list gives way in a full tile: without this a 55-task list squashed the badges
     line and the progress bar, moving that tile's bar 4px off its neighbours' (#83) */
  .view-all .project-card:not(.is-collapsed) > :not(.project-body){flex-shrink:0;}
  .energy-grid.focus-grid{grid-template-columns:repeat(auto-fill, minmax(190px, 1fr));}
  .drawer-backdrop{display:none;}
  .project-sidebar{
    /* sized from the measured topbar (--topbar-h, js/app.js) so it fits between the topbar and the
       page's bottom padding: at 100vh - 100px it overran by ~50px, and at the page's end the sticky
       box was pushed up under the topbar, hiding "Projects" and cutting off "+ Add" */
    position:sticky; top:calc(var(--topbar-h, 67px) + 17px); left:auto; z-index:auto;
    width:auto; height:auto; max-height:calc(100vh - var(--topbar-h, 67px) - 100px); overflow-y:auto;
    transform:none; transition:none; visibility:visible;
    background:none; border-right:1px solid var(--line); border:none; border-radius:0; padding:0 20px 16px 0;
  }
}
/* js/render.js only ever adds .is-selected/aria-current to a row in the "One" view, so this needs
   no extra scoping by view -- it just paints the highlight when that class is there. */
.sidebar-project.is-selected{background:var(--surface-2); font-weight:700;}
.sidebar-head{display:flex; align-items:baseline; justify-content:space-between; gap:8px;}
.sidebar-head-right{display:flex; align-items:baseline; gap:10px;}
.sidebar-title{font-size:var(--text-h); font-style:italic;}
/* The "+ New" panel (PR 7, Q29a): opens right under the header row, above the All/One switch. See
   docs/4-systems/styling.md#add-a-project-or-a-repo. */
.new-panel{border:1px solid var(--line); border-radius:var(--r-control); padding:12px; margin:10px 0; display:flex; flex-direction:column; gap:10px;}
.new-panel-section{display:flex; flex-direction:column; gap:6px;}
.repo-list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:4px; max-height:220px; overflow-y:auto;}
.repo-row{display:flex; align-items:center; gap:8px; padding:4px 0;}
.repo-name{flex:1 1 auto; min-width:0; overflow-wrap:anywhere; font-size:var(--text-sm);}
.repo-filter{padding:6px 10px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink); font-size:var(--text-sm);}
.new-repo-disclosure{font-size:var(--text-sm);}
.new-repo-disclosure summary{cursor:pointer; color:var(--accent); font-weight:600;}
.new-repo-form{display:flex; flex-direction:column; gap:8px; margin-top:8px;}
.new-repo-form input[type="text"]{padding:7px 12px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink);}
.field-error{color:var(--danger);}
.link-repo-panel{flex-basis:100%; margin-top:8px;}
.sidebar-search{flex:none; width:100%; padding:8px 12px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink);}
.sidebar-pills{gap:5px;}
.sidebar-pills .filter-pill{padding:4px 10px; font-size:var(--text-sm);}
.sidebar-tools{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:6px;}
.sidebar-tools .project-sort-select{flex:1 1 auto; min-width:0;}
.sidebar-list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:2px; border-top:1px solid var(--line); padding-top:8px;}
.sidebar-project{
  width:100%; display:flex; align-items:center; gap:9px; padding:7px 8px; border:none; border-radius:var(--r-control);
  background:none; color:var(--ink); text-align:left; font-weight:600;
}
.sidebar-project:hover{background:var(--surface-2);}
.sidebar-project .dot{width:9px; height:9px; border-radius:50%; background:var(--dot); flex:none;}
.sidebar-name{flex:1; min-width:0; overflow-wrap:break-word;}
.sidebar-count{color:var(--ink-faint); font-size:var(--text-sm); font-variant-numeric:tabular-nums;}
/* A project's own colour is identity only (Q4b): its dot, and this 3px top edge — the flat card's
   separating rule, in its colour. */
.project-card{border-top:3px solid var(--proj-color);}
/* Line 1 never wraps its controls onto a second line (#83): the name is the only thing allowed to
   grow, the collapse toggle + Edit link stay put on the right. Line 2 (badges) always renders, even
   empty, so every card's progress bar sits the same distance from its top. */
.project-head{display:flex; align-items:flex-start; justify-content:space-between; gap:10px; flex-wrap:nowrap;}
.project-title{display:flex; align-items:flex-start; gap:8px; min-width:0; flex:1 1 auto;}
/* beside the name's first line, not halfway down a name that wraps */
.project-title .dot{width:10px; height:10px; margin-top:.45em; border-radius:50%; background:var(--proj-color); display:inline-block; flex:none;}
.project-title h3{font-size:var(--text-h); overflow-wrap:break-word; min-width:0;}
.project-head-right{display:flex; align-items:center; gap:8px; flex:none; white-space:nowrap;}
.collapse-toggle{font-size:var(--text-h); line-height:1; padding:0 2px;}
.project-badges{display:flex; align-items:center; gap:8px; flex-wrap:wrap; min-height:1.4em; margin:6px 0 10px;}
.project-edit-panel{display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:10px 0; margin-bottom:10px; border-top:1px dashed var(--line); border-bottom:1px dashed var(--line); font-size:var(--text-sm);}
.project-edit-cat{display:flex; align-items:center; gap:6px; color:var(--ink-soft); font-weight:600;}
.project-edit-cat select{padding:5px 9px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink); font-size:var(--text-sm);}
.add-task-toggle{margin-top:12px; color:var(--accent); font-weight:600;}
.task-edit-actions{flex:1 1 100%; display:flex; flex-wrap:wrap; align-items:center; gap:4px 14px; font-size:var(--text-sm);}
.task-edit-actions .link-btn{background:none; color:var(--accent); padding:2px 0; font-size:var(--text-sm);}
.task-edit-actions a.link-btn{text-decoration:none;}
.task-edit-actions a.link-btn:hover{text-decoration:underline;}
.task-edit-actions .btn-text{margin-left:auto;}
.progress-track{height:5px; border-radius:var(--r-pill); background:var(--surface-2); overflow:hidden; margin-bottom:14px;}
/* Progress fill is neutral, not the project's colour — the project's colour is identity only (its
   dot and card edge), not a status indicator (Q4b). */
.progress-fill{height:100%; background:var(--ink-soft);}
.task-group{margin-bottom:10px;}
.group-label{margin-bottom:6px;}
.task-row{
  /* the chips column is as wide as its chips need, up to half the row (fit-content): one short chip
     takes little room, several sit side by side and wrap into a small block; the title gets the
     rest. The ceiling (--chips-max, set per row from the title's length by chipsMaxPct in
     js/render.js) drops toward a third for long titles. Neither ever enters the other's column (#97, #92, reworked 2026-09-28) */
  display:grid; grid-template-columns:auto minmax(0,1fr) fit-content(var(--chips-max, 50%)); column-gap:10px; align-items:start;
  padding:7px 0; border-top:1px solid var(--line);
}
/* the chips wrap inside their column rather than widen it past half the row; a chip still too
   long for it is cut with an ellipsis (its full name is in title/aria-label and the editor) */
.task-chips{display:flex; flex-wrap:wrap; justify-content:flex-end; align-content:flex-start; gap:6px; min-width:0;}
.task-chips .chip{max-width:100%; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; box-sizing:border-box;}
.task-group .task-row:first-of-type{border-top:none;}
.task-row input[type="checkbox"]{width:17px; height:17px; margin-top:3px; accent-color:var(--accent); flex:none;}
.task-title{min-width:0; overflow-wrap:anywhere;}
.task-row.is-done .task-title{color:var(--ink-faint); text-decoration:line-through;}
.task-title[role="button"]{cursor:pointer;}
/* Claude provenance marks after the title (#104): quiet and faint, never a chip */
.claude-mark{display:inline-block; margin-left:6px; vertical-align:-2px; color:var(--ink-faint); line-height:0; text-decoration:none;}
.claude-mark svg{width:14px; height:14px; display:block;}
.task-title[role="button"]:hover{text-decoration:underline; text-decoration-style:dotted;}
a.task-title{color:inherit; text-decoration:none;}
a.task-title:hover{text-decoration:underline;}
.task-edit-form{display:flex; flex-wrap:wrap; gap:6px; padding:7px 0; border-top:1px solid var(--line); width:100%;}
.task-edit-form input[type="text"]{flex:1 1 160px; min-width:0; padding:6px 9px; border:1px solid var(--accent); border-radius:var(--r-control); background:var(--surface); color:var(--ink);}
.task-edit-form select,.task-edit-form input[type="date"]{padding:6px 8px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink);}
.task-edit-form button{padding:6px 12px; border:none; border-radius:var(--r-control); font-weight:600;}
.task-edit-form button[type="submit"]{background:var(--accent); color:var(--accent-ink);}
.task-edit-form button[type="button"]{background:var(--surface-2); color:var(--ink-soft);}
.task-edit-form textarea,.add-task-form textarea{
  flex:1 1 160px; min-width:0; padding:6px 9px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink); font:inherit; resize:vertical;
}
.done-group{margin-top:4px;}
.label-picker{flex:1 1 100%; font-size:var(--text-sm);}
.label-picker summary{cursor:pointer; color:var(--ink-soft); font-weight:600; padding:4px 0;}
.label-options{display:flex; flex-wrap:wrap; gap:6px; margin:6px 0;}
.label-option{
  display:inline-flex; align-items:center; gap:5px; padding:3px 9px 3px 6px; border-radius:var(--r-pill); cursor:pointer;
  background:color-mix(in srgb, var(--chip-color) 12%, transparent); color:color-mix(in srgb, var(--chip-color) 55%, var(--ink)); font-weight:600;
}
.label-option input{accent-color:var(--chip-color); margin:0;}
.label-swatch{width:22px; height:22px; padding:1px; border-radius:50%;}
.label-picker input[type="text"]{width:100%; padding:6px 9px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink); font-size:var(--text-sm);}
.due-defaults-form{display:flex; flex-wrap:wrap; align-items:center; gap:10px 18px; margin:12px 0;}
.due-defaults-form label{display:inline-flex; align-items:center; gap:6px;}
.due-defaults-form input[type="number"]{width:4.5rem; padding:6px 8px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink);}
.due-step{flex:1 0 100%; display:flex; flex-wrap:wrap; align-items:center; gap:6px; font-size:var(--text-sm); color:var(--ink-soft);}
.due-step select{font-size:var(--text-sm); padding:4px 6px;}
.add-task-form .due-step button,.task-edit-form .due-step button[type="button"]{background:none; color:var(--accent); padding:2px 4px; font-size:var(--text-sm); font-weight:600; border-radius:var(--r-control);}
.add-task-form .due-step button:hover,.task-edit-form .due-step button[type="button"]:hover{text-decoration:underline;}
.add-task-form{display:flex; flex-wrap:wrap; gap:6px; margin-top:12px; border-top:1px dashed var(--line); padding-top:12px;}
.add-task-form input[type="text"]{
  flex:1 1 140px; min-width:0; padding:7px 10px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink);
}
.add-task-form select,.add-task-form input[type="date"]{
  padding:7px 8px; border:1px solid var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink);
}
.add-task-form button{
  padding:7px 13px; border:none; border-radius:var(--r-control); background:var(--accent); color:var(--accent-ink); font-weight:700;
}
.add-project-form{display:flex; gap:8px;}
/* in the narrow project list the add field takes its own row, so its placeholder isn't cut off */
.project-sidebar .add-project-form{flex-wrap:wrap;}
.project-sidebar .add-project-form input[type="text"]{flex-basis:100%;}
.add-project-form input[type="text"], .add-project-form input[type="password"]{
  flex:1; min-width:0; padding:11px 14px; border:1.5px dashed var(--line); border-radius:var(--r-control); background:transparent; color:var(--ink);
}
.add-project-form select{
  /* doc-ref 63c4 docs/4-systems/pwa-shell.md */
  padding:11px 10px; border:1.5px dashed var(--line); border-radius:var(--r-control); background:var(--surface); color:var(--ink);
}
.add-project-form button{
  padding:11px 18px; border:none; border-radius:var(--r-control); background:var(--accent); color:var(--accent-ink); font-weight:600; white-space:nowrap;
}

.toast{
  position:fixed; z-index:20;
  left:50%; transform:translateX(-50%);
  bottom:calc(16px + env(safe-area-inset-bottom, 0px));
  width:min(728px, calc(100% - 32px));
  display:flex; align-items:flex-start; gap:10px;
  padding:12px 8px 12px 14px;
  background:var(--surface); color:var(--ink);
  border:1px solid var(--accent); border-left-width:4px; border-radius:var(--r-control);
  box-shadow:var(--shadow);
}
.toast-error{border-color:var(--danger);}
/* room to scroll the last controls clear of the toast while it is showing */
.wrap:has(.toast){padding-bottom:calc(160px + env(safe-area-inset-bottom, 0px));}
.toast-text{flex:1; margin:0; font-size:var(--text-sm); line-height:1.4; overflow-wrap:anywhere;}
.toast-close{
  flex:none; min-width:32px; min-height:32px; padding:0;
  border:none; border-radius:var(--r-control); background:none; color:var(--ink-soft); font-size:var(--text-h); line-height:1; cursor:pointer;
}

/* PWA install polish — hides browser chrome-shaped gaps when running standalone */
@media (display-mode: standalone) {
  .topbar { padding-top: max(16px, env(safe-area-inset-top)); }
}

/* Dragging projects into order (PR 9). The grip on a project header, the sidebar rows as their own
   handles, and what shows while one is being carried: a lifted ghost that follows the pointer, the
   original's place as a dashed placeholder, and a drop line where it will land. Only the ghost
   gets a shadow (the cards are flat). See docs/4-systems/styling.md#dragging-projects */
.drag-grip{
  flex:none; display:inline-flex; align-items:center; justify-content:center;
  width:28px; height:28px; margin:-2px -4px -2px -6px; padding:0; border:none; border-radius:var(--r-control);
  background:none; color:var(--ink-soft); cursor:grab;
  /* the grip never scrolls the page: a touch on it is a drag (after the hold) or nothing */
  touch-action:none;
}
.drag-grip:hover{background:var(--surface-2); color:var(--ink-soft);}
@media (pointer:coarse){ .drag-grip{width:36px; height:36px; margin:-6px -6px -6px -8px;} }
/* sidebar rows are drag handles as a whole: no text selection or touch callout on a long press, but
   vertical panning stays, so a swipe still scrolls the drawer */
.sidebar-project{-webkit-user-select:none; user-select:none; -webkit-touch-callout:none; touch-action:pan-y;}
body.is-dragging, body.is-dragging *{cursor:grabbing !important; -webkit-user-select:none; user-select:none;}
.drag-ghost{
  position:fixed; top:0; left:0; z-index:1000; margin:0; pointer-events:none;
  background:var(--surface); border-radius:var(--r-card);
  box-shadow:0 10px 28px rgba(28,36,34,.22), 0 2px 6px rgba(28,36,34,.12);
  opacity:1;
}
.drag-ghost.is-row{border-radius:var(--r-control); padding:7px 8px;}
.drag-ghost.is-card{border:1px solid var(--line); border-top:3px solid var(--proj-color); overflow:hidden;}
.drag-placeholder{
  outline:2px dashed var(--ink-faint); outline-offset:-2px; background:var(--surface-2); box-shadow:none;
  border-radius:var(--r-card);
}
.sidebar-list li.drag-placeholder{border-radius:var(--r-control);}
.drag-placeholder > *{visibility:hidden;}
.drop-indicator{position:fixed; z-index:1001; pointer-events:none; background:var(--accent); border-radius:2px;}
.drop-indicator[hidden]{display:none;}
/* the live region for "moved to position N of M": present for screen readers, invisible */
.sr-only{position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;}

/* Dragging tasks (PR 11). A small grip before the checkbox on every open row, the empty groups' "Drop
   here" zones (shown only while a task is carried), the minimised card / empty group that would take
   the drop, and the Move confirmation. The ghost, dashed placeholder and drop line are the ones the
   project drag uses (above). See docs/4-systems/styling.md#dragging-tasks */
.task-row.has-grip{grid-template-columns:auto auto minmax(0,1fr) fit-content(var(--chips-max, 50%)); column-gap:8px;}
.task-grip{
  flex:none; display:inline-flex; align-items:center; justify-content:center;
  width:22px; height:24px; margin:0 -2px 0 -6px; padding:0; border:none; border-radius:var(--r-control);
  background:none; color:var(--ink-soft); cursor:grab; touch-action:none;
}
.task-grip svg{width:13px; height:13px;}
.task-grip:hover{background:var(--surface-2); color:var(--ink-soft);}
@media (pointer:coarse){ .task-grip{width:30px; height:30px; margin:-3px -4px -3px -8px;} .task-grip svg{width:15px; height:15px;} }
.task-group.is-empty{display:none;}
body.is-dragging-task .task-group.is-empty{display:block;}
body.is-dragging-task .empty-note{display:none;}
.drop-zone{
  padding:10px; border:1.5px dashed var(--line); border-radius:var(--r-control);
  text-align:center; font-size:var(--text-sm); color:var(--ink-faint);
}
.task-group.drop-target .drop-zone{border-color:var(--accent); color:var(--accent);}
.project-card.drop-target{outline:2px solid var(--accent); outline-offset:-2px;}
.drag-ghost.is-task{border:1px solid var(--line); border-radius:var(--r-control); padding:7px 8px; box-sizing:border-box;}
.task-row.drag-placeholder{border-radius:var(--r-control);}
.move-dialog-backdrop{
  position:fixed; inset:0; z-index:1100; display:flex; align-items:center; justify-content:center;
  padding:16px; background:rgba(28,36,34,.4);
}
.move-dialog{
  width:100%; max-width:420px; padding:18px; background:var(--surface); color:var(--ink);
  border:1px solid var(--line); border-radius:var(--r-control); box-shadow:var(--shadow);
}
.move-dialog-text{margin:0 0 16px; line-height:1.5; overflow-wrap:anywhere;}
.move-dialog-actions{display:flex; justify-content:flex-end; align-items:center; gap:8px;}
