/* App styles, taken from docs/prototype.html (lines 10–360 of its <style>, and its
   sign-in block, added below in 7a). Left out: the prototype-only "show first run"
   scaffolding. The first-run screen has its own stylesheet, firstrun.css. */

/* One theme only: a dark room with one light in it, the same as the landing page.
   Every colour is set explicitly so it doesn't depend on the browser's defaults.
   Warm colours are for the user's actions and for anything over its estimate; cool
   colours are for data and for whatever is currently in progress. */
:root {
  --ground: #07080b;
  --rail:   #0b0d12;
  --panel:  #12151b;
  --panel2: #0f1218;
  --raise:  #171b22;
  --raise2: #1c212a;
  --line:   #171b22;
  --line2:  #232932;
  --line3:  #2f3a47;
  --ink:    #e4e8ee;
  --ink2:   #b9c0ca;
  --muted:  #7c8694;
  --faint:  #6b7481;
  --dim:    #4a5260;
  --blue:   #5b9dd9;
  --blue-d: #4e91cf;
  --amber:  #e0a355;
  --amber-2:#f2c98a;
  --amber-d:#bd8228;
  color-scheme: dark;
}

html, body { height: 100%; }
body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;
  font-size: 13px;
  line-height: 1.45;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}
* { box-sizing: border-box; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
button:focus-visible, [tabindex]:focus-visible, select:focus-visible, input:focus-visible {
  outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 6px;
}
.num { font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace; font-variant-numeric: tabular-nums; }
/* one session's time, or one day's: "1 h 25 min" wraps whole, never leaving "25 min" on a line of its own */
.dur { white-space: nowrap; }

/* grain over everything, very faint, so the flat dark reads as material */
body::after {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 50;
  opacity: .028; mix-blend-mode: screen;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .9 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

.app { display: flex; height: 100%; }

/* ---- rail ---- */
.rail {
  width: 200px; flex-shrink: 0; background: var(--rail);
  border-right: 1px solid var(--line2);
  padding: 18px 0 calc(14px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column; gap: 22px;
}
.brand { padding: 0 16px; display: flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.brand .dot {
  width: 18px; height: 18px; border-radius: 6px; flex-shrink: 0;
  background: radial-gradient(circle at 50% 45%, #fff2d8 0, #f2c98a 22%, #e0a355 48%, #6a4212 100%);
  box-shadow: 0 0 16px rgba(224,163,85,.5), inset 0 0 0 1px rgba(255,255,255,.08);
}
.navlist { display: flex; flex-direction: column; gap: 2px; padding: 0 8px; }
.navlist button { padding: 7px 10px; border-radius: 7px; text-align: left; color: var(--muted); transition: color .15s, background .15s; }
.navlist button:hover { color: var(--ink2); background: var(--raise); }
.navlist a { padding: 7px 10px; border-radius: 7px; color: var(--muted); text-decoration: none; transition: color .15s, background .15s; }
.navlist a:hover { color: var(--ink2); background: var(--raise); }
.navlist a[aria-current="page"] { background: var(--raise2); color: var(--ink); font-weight: 500; box-shadow: 0 1px 0 rgba(255,255,255,.03) inset; }
.navlist button[aria-current="page"] { background: var(--raise2); color: var(--ink); font-weight: 500; box-shadow: 0 1px 0 rgba(255,255,255,.03) inset; }
/* how many requests are waiting, beside Requests in the rail and the phone strip */
.railreq { margin-left: 6px; font-size: 12px; color: var(--amber-2); font-weight: 400; }
.viewnav a { text-decoration: none; }
.kv { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.kv > span:first-child { font-size: 11px; color: var(--muted); }

/* ---- main ---- */
.main {
  flex-grow: 1; display: flex; flex-direction: column; min-width: 0;
  /* the one light in the room, spilling down from the top edge */
  background:
    radial-gradient(55% 260px at 50% 0%, rgba(224,163,85,.075), rgba(224,163,85,0) 70%),
    var(--ground);
}
/* the top bar on every page: sign-out on the right, and the logo on the left only
   where the rail is hidden */
.topbar { flex-shrink: 0; display: flex; align-items: center; justify-content: flex-end; gap: 12px; padding: 8px 18px 0; }
.topbar .brand { display: none; padding: 0; margin-right: auto; }
.viewnav { display: none; gap: 6px; padding: 10px 16px 0; overflow-x: auto; flex-shrink: 0; }
.viewnav button, .viewnav a {
  flex-shrink: 0; padding: 6px 13px; border-radius: 16px; border: 1px solid var(--line2);
  font-size: 13px; color: var(--muted); white-space: nowrap; background: rgba(12,14,19,.6);
}
.viewnav a[aria-current="page"],
.viewnav button[aria-current="page"] { background: var(--raise2); border-color: var(--line3); color: var(--ink); font-weight: 500; }

.bar[hidden] { display: none; }
.bar {
  flex-shrink: 0; min-height: 52px; border-bottom: 1px solid var(--line2);
  display: flex; align-items: center; gap: 4px; padding: 8px 18px; flex-wrap: wrap;
  position: relative;
}
.bar::before {
  /* lit top edge, brightest in the middle, like the frame on the landing page */
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(242,201,138,.35) 40%, rgba(255,241,211,.6) 50%, rgba(242,201,138,.35) 60%, transparent);
  pointer-events: none;
}
.barend { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* the board's filter (board.jte): two compact dropdowns beside New task */
.filter { display: flex; align-items: center; gap: 6px; margin-left: 8px; flex-wrap: wrap; }
.filter select { width: auto; max-width: 190px; min-height: 32px; padding: 0 8px; border-radius: 8px; font-size: 12px; color-scheme: dark; }
.filter.auto button { display: none; }   /* board.js submits on change */
.filter .clear { font-size: 12px; color: var(--muted); }
.filter .clear:hover { color: var(--ink2); }
.btn { padding: 6px 13px; border-radius: 8px; border: 1px solid var(--line3); font-size: 12px; font-weight: 500; color: var(--ink2); transition: border-color .15s, color .15s, box-shadow .15s; }
.btn:hover { border-color: #3c4857; color: var(--ink); }
.btn.primary {
  border-color: rgba(224,163,85,.55); color: var(--amber-2);
  background: linear-gradient(180deg, rgba(224,163,85,.14), rgba(224,163,85,.04));
  box-shadow: 0 0 22px rgba(224,163,85,.12);
}
.btn.primary:hover { border-color: rgba(242,201,138,.8); box-shadow: 0 0 28px rgba(224,163,85,.22); }

.tabs { display: none; gap: 6px; padding: 10px 16px 0; overflow-x: auto; flex-shrink: 0; }
.tabs button, .tabs a {
  flex-shrink: 0; padding: 7px 13px; border-radius: 16px;
  border: 1px solid var(--line2); font-size: 13px; color: var(--muted); white-space: nowrap; background: rgba(12,14,19,.6);
}
.tabs a { text-decoration: none; }
.tabs button[aria-selected="true"], .tabs a[aria-current="page"] { background: var(--raise2); border-color: var(--line3); color: var(--ink); font-weight: 500; }

/* ---- board ---- */
.board {
  flex-grow: 1; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px; padding: 16px 18px calc(16px + env(safe-area-inset-bottom, 0px));
  min-height: 0; overflow: hidden;
}
.col { display: flex; flex-direction: column; gap: 8px; min-width: 0; min-height: 0; }
.colhead { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 0 2px; flex-shrink: 0; }
.colhead > :last-child { text-align: right; }
.colhead .name { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.drop { flex-grow: 1; display: flex; flex-direction: column; gap: 8px; overflow-y: auto; border-radius: 10px; padding: 1px; min-height: 40px; }
.drop.can { box-shadow: inset 0 0 0 1px rgba(91,157,217,.22); }
.drop.over { background: rgba(91,157,217,.06); box-shadow: inset 0 0 0 1px rgba(91,157,217,.5); }

/* Groups in a column (group.jte): a bracket in the left margin for each domain,
   project and abstract task, with its name running up the bracket. The name's
   background breaks the bracket's line, so the label sits on it rather than beside
   it and a level costs 16px, not twice that. Colours as in first run's levels:
   domain amber, project blue, abstract task dashed grey.

   A group is a row: a 15px column as tall as the group holding the name, then the
   cards. The name is centred in that column and sticky, so on a bracket taller than
   the scrolling column it stays at the top (or bottom) edge while any of its
   bracket is in view, and leaves with the bracket's end. The column has to be a
   real flex item for that: an absolutely positioned label can't be sticky. */
.grp { position: relative; display: flex; min-width: 0; }
.grp::before {
  content: ""; position: absolute; left: 7px; top: 2px; bottom: 2px; width: 5px;
  border: 1px solid var(--line3); border-right: none; border-radius: 4px 0 0 4px;
  pointer-events: none;
}
.grp.domain::before { border-color: rgba(242,201,138,.38); }
.grp.project::before { border-color: rgba(143,184,224,.38); }
/* the three sides by name: border-style would also turn the right side back on, at
   the browser's default width and the text's colour */
.grp.abstract::before { border-left-style: dashed; border-top-style: dashed; border-bottom-style: dashed; }
.gbody { flex: 1 1 auto; min-width: 0; margin-left: 1px; display: flex; flex-direction: column; gap: 8px; }
/* contain: size keeps a long name from making the group taller than its cards; the
   column still stretches to the group's height, and the name is cut to fit that */
.glabel {
  flex: 0 0 15px; position: relative; z-index: 1; contain: size;
  display: flex; flex-direction: column; justify-content: center; align-items: center; text-decoration: none;
}
.glabel span {
  position: sticky; top: 4px; bottom: 4px;
  writing-mode: vertical-rl; transform: rotate(180deg);   /* reads bottom to top */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-height: calc(100% - 10px);
  padding: 4px 0; background: var(--ground);
  font-size: 12.5px; line-height: 15px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted);
}
.grp.domain > .glabel span { color: rgba(242,201,138,.8); }
.grp.project > .glabel span { color: rgba(143,184,224,.85); }
.glabel:hover span { color: var(--ink); }

.card {
  background: var(--panel); border: 1px solid var(--line2); border-radius: 9px; padding: 10px 12px; flex-shrink: 0;
  box-shadow: 0 1px 0 rgba(255,255,255,.025) inset, 0 6px 18px rgba(0,0,0,.28);
  transition: border-color .15s, transform .15s;
}
/* draggable where board.js drags (9.13): a desktop pointer, five columns, and somewhere to go */
@media (min-width: 901px) and (pointer: fine) {
  .card[data-moves]:not([data-moves=""]) { cursor: grab; }
  .card[data-moves]:not([data-moves=""]):hover { border-color: var(--line3); }
}
.card.dragging { opacity: .4; }
.card .ctx { font-size: 11px; color: var(--faint); margin-bottom: 5px; }
.card .row { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
/* In a narrow column the title keeps room for a few words, and "log time" and the
   estimate drop to the next line instead of squeezing it to a letter per line. */
.card .row { flex-wrap: wrap; }
.card .title { flex: 1 1 7em; min-width: 0; overflow-wrap: break-word; }
.card .row > a:not(.title), .card .est { white-space: nowrap; }
.card .est { margin-left: auto; }   /* stays on the right, even on a line of its own */
/* "log time": an action, so in the warm colour, and smaller than the title */
.card .row > a:not(.title) { font-size: 12px; color: var(--amber-2); text-underline-offset: 2px; text-decoration-color: rgba(242,201,138,.4); }
.card .est { flex-shrink: 0; color: var(--muted); }
.card .meta { font-size: 11px; margin-top: 6px; color: var(--dim); }
.card .meta.warn { color: var(--amber); }
.card.active { border-color: var(--line3); box-shadow: -2px 0 0 var(--blue), 0 1px 0 rgba(255,255,255,.025) inset, 0 6px 18px rgba(0,0,0,.28); }
.card.done { background: var(--panel2); border-color: var(--line); box-shadow: none; }
.card.done .title { color: var(--muted); }
.bar-track { margin-top: 7px; height: 3px; border-radius: 2px; background: var(--line2); overflow: hidden; }
.bar-fill { height: 100%; background: var(--blue-d); }
.bar-fill.over { background: var(--amber-d); }
.cardfoot { display: flex; gap: 8px; margin-top: 10px; }
.cardfoot button { flex-grow: 1; min-height: 36px; border-radius: 8px; border: 1px solid var(--line2); font-size: 12px; color: var(--ink2); }
.cardfoot button.go { background: var(--raise2); border-color: var(--line3); font-weight: 500; color: var(--ink); }
/* splitting a task (build-order 9.8) */
.splitpage { width: min(520px, 100%); }
.splitrow { display: flex; gap: 8px; }
.splitrow input[type="text"] { flex: 1 1 auto; }
.splitrow input[type="number"] { width: 96px; flex-shrink: 0; min-height: 44px; padding: 0 10px; border-radius: 10px;
  border: 1px solid var(--line3); background: var(--ground); color: var(--ink); font: inherit; }
.carddelete { display: inline-block; margin-top: 8px; font-size: 11px; color: var(--dim); text-decoration: none; }
.carddelete:hover { color: var(--amber-2); text-decoration: underline; text-underline-offset: 2px; }
/* an abstract task's placeholder: dashed, because it isn't work you can pick up yet */
.card.abstract { border-style: dashed; border-color: var(--line3); box-shadow: none; }
.cardfoot a.go {
  flex-grow: 1; min-height: 36px; display: flex; align-items: center; justify-content: center;
  border-radius: 8px; border: 1px solid var(--line3); background: var(--raise2);
  font-size: 12px; font-weight: 500; color: var(--ink); text-decoration: none;
}
.empty { font-size: 12px; color: var(--dim); padding: 10px 2px; }

/* ---- pages ---- */
.page {
  flex-grow: 1; overflow-y: auto; min-height: 0;
  padding: 22px 26px calc(28px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column; gap: 20px;
}
.pagehead { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.pagehead h1 {
  margin: 0; font-size: 22px; font-weight: 600; letter-spacing: -.02em;
  background: linear-gradient(180deg, #ffffff 0%, #dfe4ec 55%, #aab3c0 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pagehead .sub { font-size: 12px; color: var(--faint); }
.pagehead .hint { text-align: right; }
.panel {
  background: var(--panel); border: 1px solid var(--line2); border-radius: 12px; padding: 18px 20px;
  box-shadow: 0 1px 0 rgba(255,255,255,.025) inset, 0 10px 30px rgba(0,0,0,.3);
}
.panel h2 { margin: 0 0 4px; font-size: 14px; font-weight: 500; }
.panel .note { font-size: 12px; color: var(--faint); margin-bottom: 14px; }
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; }
.tile {
  background: var(--panel); border: 1px solid var(--line2); border-radius: 12px; padding: 14px 16px;
  box-shadow: 0 1px 0 rgba(255,255,255,.025) inset, 0 10px 30px rgba(0,0,0,.3);
}
.tile .lab { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
.tile .big {
  font-size: 28px; font-weight: 500; letter-spacing: -.02em;
  background: linear-gradient(180deg, #ffffff 0%, #dfe4ec 55%, #aab3c0 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.tile .big .unit { font-size: 16px; letter-spacing: 0; }
.tile .sub { font-size: 12px; color: var(--faint); margin-top: 4px; }
.split { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 16px; align-items: start; }
.rows { display: flex; flex-direction: column; gap: 14px; }
.subtle { font-size: 11px; color: var(--faint); }
.warn { color: var(--amber); }
.chartwrap { overflow-x: auto; }
/* the estimate curve, drawn by the server (build-order 9.5), in the prototype's colours */
svg.curve { width: 100%; max-width: 620px; height: auto; display: block; }
svg.curve .grid { stroke: #232932; stroke-width: 1; }
svg.curve .axis { stroke: #2f3a47; stroke-width: 1; }
svg.curve .tick, svg.curve .date { fill: #6b7481; font-size: 11px; font-family: "IBM Plex Mono", monospace; }
svg.curve .area { fill: #bd8228; fill-opacity: .13; }
svg.curve .line { fill: none; stroke: #bd8228; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
svg.curve .dot { fill: #bd8228; stroke: #12151b; stroke-width: 2; }
svg.curve .endlabel { fill: #a8b0ba; font-size: 12px; font-family: "IBM Plex Mono", monospace; }
svg.curve .endlabel.now { fill: #e4e8ee; font-size: 13px; font-weight: 500; }
svg.curve .worked { fill: none; stroke: #4e91cf; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
svg.curve .workeddot { fill: #4e91cf; stroke: #12151b; stroke-width: 2; }
svg.curve .endlabel.worked { fill: #8fb8e0; stroke: none; font-size: 12px; }
/* the milestone burn (build-order 9.10): a week's hours as a bar, the needed rates across */
svg.curve .bar { fill: #4e91cf; fill-opacity: .8; }
svg.curve line.needed { stroke: #bd8228; stroke-width: 2; stroke-dasharray: 6 4; }
svg.curve line.corrected { stroke: #e0a355; stroke-width: 1.5; stroke-dasharray: 2 3; }
/* the rates' labels: a halo in the panel's colour, painted under the letters, so a
   label stays readable where it crosses a bar or a line. Scoped to text, because a
   class shared with the line would otherwise dash the letters' outlines too. */
svg.curve text.needed, svg.curve text.corrected { stroke: #12151b; stroke-width: 4px; stroke-linejoin: round; stroke-dasharray: none; paint-order: stroke; }
svg.curve text.needed { fill: #e0a355; }
svg.curve text.corrected { fill: #f2c98a; }
/* a child row with a form beside it: an attached abstract task and its Detach */
.kidrow { display: flex; align-items: center; gap: 8px; }
.kidrow .kid { flex: 1 1 auto; min-width: 0; }
.attachform { display: flex; gap: 6px; align-items: center; margin-left: auto; }
.attachform select { max-width: 200px; }
/* changing and ending things (build-order 9.16), folded away until opened */
details.changes { border: 1px solid var(--line2); border-radius: 10px; padding: 8px 12px; }
details.changes > summary { cursor: pointer; font-size: 12px; color: var(--muted); }
details.changes[open] > summary { margin-bottom: 10px; }
.changeforms { display: flex; flex-direction: column; gap: 12px; }
.changeform { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.changeform label { font-size: 12px; color: var(--muted); min-width: 110px; }
.changeform input[type="text"], .changeform select { width: auto; flex: 1 1 220px; min-height: 36px; }
.changeform input[type="number"] { width: 110px; min-height: 36px; padding: 0 10px; border-radius: 8px;
  border: 1px solid var(--line3); background: var(--ground); color: var(--ink); font: inherit; }
.changeform .hint, .confirmdelete span { font-size: 11.5px; color: var(--dim); }
.btn.danger { color: var(--amber-2); border-color: rgba(242,201,138,.45); text-decoration: none; }
.confirmdelete { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px;
  border: 1px solid rgba(242,201,138,.45); background: rgba(224,163,85,.07); }
.confirmdelete span { color: var(--ink2); font-size: 12.5px; flex: 1 1 260px; }
.confirmdelete a { font-size: 12px; color: var(--muted); }
.changeproblem { margin: 0; }
details.fixsession > summary { cursor: pointer; font-size: 11px; color: var(--dim); }
details.fixsession form { display: flex; gap: 6px; margin-top: 6px; justify-content: flex-end; }
details.fixsession input[type="number"] { width: 70px; min-height: 30px; padding: 0 6px; border-radius: 6px;
  border: 1px solid var(--line3); background: var(--ground); color: var(--ink); font: inherit; }
details.fixsession select { width: auto; min-height: 30px; }
/* wraps onto a second line in a narrow table cell rather than pushing the panel wider */
details.fixsession form { align-items: center; flex-wrap: wrap; max-width: 260px; margin-left: auto; }
details.fixsession .unit { font-size: 11px; color: var(--muted); }

/* comments (comments.jte): a dated log under the page's other panels */
.addcomment, .editcomment form { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.addcomment textarea, .editcomment textarea {
  width: 100%; resize: vertical; padding: 10px 12px; border-radius: 10px; font: inherit; font-size: 13px;
  background: var(--ground); border: 1px solid var(--line3); color: var(--ink);
}
.addcomment .btn, .editcomment .btn { min-height: 36px; }
.comments { display: flex; flex-direction: column; margin-top: 12px; }
.comment { padding: 12px 0; border-top: 1px solid var(--line2); }
.comment .when { font-size: 11px; color: var(--faint); margin-bottom: 4px; }
.comment .body { font-size: 13px; color: var(--ink2); white-space: pre-wrap; overflow-wrap: break-word; }
details.editcomment { margin-top: 6px; }
details.editcomment > summary { cursor: pointer; font-size: 11px; color: var(--dim); }
details.editcomment form { margin-top: 8px; }

/* the hours heatmap (build-order 9.17): an empty day is the panel's own colour */
.heat { display: flex; flex-direction: column; gap: 6px; overflow-x: auto; }
.heatmonths, .heatgrid { display: flex; gap: 2px; }
.heatmonths span { width: 11px; flex-shrink: 0; font-size: 10px; color: var(--muted); white-space: nowrap; overflow: visible; }
.heatweek { display: flex; flex-direction: column; gap: 2px; }
.hc { display: inline-block; width: 11px; height: 11px; border-radius: 2px; flex-shrink: 0; background: var(--panel); }
.hc.future { visibility: hidden; }
.hc.l1 { background: #1c3550; }
.hc.l2 { background: #24507a; }
.hc.l3 { background: #3a76b0; }
.hc.l4 { background: #5b9dd9; }
.hc.fresh { background: var(--blue-d); }
.hc.fine { background: var(--dim); }
.hc.drained { background: var(--amber-d); }
a.hc:hover { outline: 1px solid var(--ink2); outline-offset: 1px; }
.hc.sel { outline: 1px solid var(--ink); outline-offset: 1px; }
/* the day log, under the day page: hours across everything beside fatigue, stacking when narrow */
.daygrids { margin: 20px auto 0; width: min(900px, 100%); display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr)); }
.heatlegend { display: flex; align-items: center; gap: 6px 12px; flex-wrap: wrap; font-size: 11px; color: var(--muted); }
/* a swatch and its label wrap together, never apart */
.heatlegend .key { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.curvefacts { display: flex; gap: 8px 20px; flex-wrap: wrap; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); font-size: 12px; color: var(--muted); }
svg { display: block; }
.legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12px; color: var(--muted); margin-top: 10px; }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; }
table { border-collapse: collapse; width: 100%; font-size: 12px; }
th { text-align: left; font-weight: 500; color: var(--muted); font-size: 11px; letter-spacing: .05em; text-transform: uppercase; padding: 0 10px 8px 0; }
td { padding: 9px 10px 9px 0; border-top: 1px solid var(--line2); vertical-align: baseline; }
td.r, th.r { text-align: right; padding-right: 0; }
td.r + td, th.r + th { padding-left: 18px; }
.pill { display: inline-block; padding: 2px 9px; border-radius: 10px; font-size: 11px; border: 1px solid var(--line3); color: var(--muted); }
.pill.fresh { color: var(--blue); border-color: #2c4459; background: rgba(91,157,217,.06); }
.pill.fine { color: var(--muted); }
.pill.drained { color: var(--amber); border-color: #4a3a22; background: rgba(224,163,85,.06); }
/* The shell is the height of the window and doesn't scroll, so a tree taller than
   the rail has room for scrolls on its own, between the sections above and below
   it, which stay put. It only shrinks once it runs out of room: a short tree sits
   as it always has. */
.projlist {
  display: flex; flex-direction: column; gap: 1px; padding: 8px 8px 0; border-top: 1px solid var(--line2); margin: 0 8px;
  flex: 0 1 auto; min-height: 0; overflow-y: auto;
}
.projlist button { padding: 6px 10px; font-size: 12px; text-align: left; color: var(--muted); border-radius: 7px; }
.projlist button:hover { color: var(--ink2); background: var(--raise); }
.projlist button[aria-current="true"] { color: var(--ink); background: var(--raise2); }
.projlist .domhead { padding: 9px 10px 3px; font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--dim); }
.projlist .domhead button { padding: 0; font-size: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; border-radius: 0; }
.projlist .domhead button:hover { background: none; color: var(--muted); }
.projlist .sub button { padding-left: 20px; }
/* the same tree, drawn with links */
.projlist a { padding: 6px 10px; font-size: 12px; color: var(--muted); border-radius: 7px; text-decoration: none; }
.projlist a:hover { color: var(--ink2); background: var(--raise); }
.projlist a[aria-current="page"] { color: var(--ink); background: var(--raise2); }
.projlist .domhead a { padding: 0; font-size: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; border-radius: 0; }
.projlist .domhead a:hover { background: none; color: var(--muted); }
.projlist .sub { display: flex; flex-direction: column; gap: 1px; }
.projlist .sub a { padding-left: 20px; }
.projlist .sub a.deeper { padding-left: 32px; font-size: 11.5px; }
.projlist a.addbtn { display: block; margin: 6px 10px 0; padding: 4px 11px; }

/* ---- record pages: the belongs-to line, and lists of children ---- */
.lnk { color: var(--ink2); border-bottom: 1px solid transparent; padding: 0; }
.lnk:hover { color: var(--ink); border-bottom-color: var(--line3); }
.crumb { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
.crumb .sep:first-child { display: none; }
.crumb .sep { color: var(--dim); }
.kids { display: flex; flex-direction: column; gap: 1px; margin: 0 -12px; }
.kid { display: block; width: 100%; text-align: left; padding: 10px 12px; border-radius: 9px; border: 1px solid transparent; }
.kid:hover { background: var(--raise); border-color: var(--line2); }
.kid .top { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.kid .nm { font-size: 13px; color: var(--ink); }
.kid .fig { flex-shrink: 0; font-size: 12px; color: var(--muted); }
.kid .sub { font-size: 11px; color: var(--dim); margin-top: 4px; display: flex; gap: 12px; flex-wrap: wrap; }
.kid .sub .stale { color: var(--amber); }

/* Adding something is always offered where its children are listed, and the
   dashed outline is the same "+ Your own" pill the landing page uses. */
.ph { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
/* written for buttons in the prototype; these are links here */
a.kid, a.addbtn, a.lnk { text-decoration: none; color: inherit; }
a.addbtn { color: var(--muted); }
.pagehead .addbtn { margin-left: auto; }
.pagehead .addbtn + .addbtn { margin-left: 0; }
.card a.title { color: inherit; text-decoration: none; }
.card a.title:hover, .card .ctx a:hover { text-decoration: underline; text-underline-offset: 2px; }
.card .ctx a { color: inherit; text-decoration: none; }
.addbtn {
  flex-shrink: 0; font-size: 12px; color: var(--muted);
  padding: 4px 11px; border-radius: 14px; border: 1px dashed var(--line3);
  transition: color .15s, border-color .15s, background .15s;
}
.addbtn:hover {
  color: var(--amber-2); border-style: solid; border-color: rgba(242,201,138,.5);
  background: rgba(224,163,85,.07);
}
.projlist .addbtn { display: block; width: calc(100% - 20px); margin: 8px 10px 0; text-align: left; }

/* ---- the task record: timeline and session rows ---- */
.tl { display: flex; flex-direction: column; }
.tl .ev { display: grid; grid-template-columns: 96px minmax(0,1fr); gap: 14px; padding: 9px 0; border-top: 1px solid var(--line2); }
.tl .ev:first-child { border-top: 0; padding-top: 0; }
.tl .ev .d { font-size: 11.5px; color: var(--muted); }
.tl .ev .w { font-size: 12.5px; color: var(--ink2); }
.tl .ev .w b { font-weight: 500; color: var(--ink); }

/* ---- dialog ---- */
dialog {
  border: 1px solid var(--line3); border-radius: 14px; background: var(--panel);
  color: var(--ink); padding: 0; width: min(420px, calc(100vw - 32px));
  box-shadow: 0 1px 0 rgba(255,255,255,.04) inset, 0 -20px 60px rgba(224,163,85,.06), 0 30px 80px rgba(0,0,0,.6);
}
dialog::backdrop { background: rgba(4,5,8,.7); backdrop-filter: blur(4px); }
.dlg { padding: 22px; display: flex; flex-direction: column; gap: 20px; }
.dlg h2 { margin: 0; font-size: 18px; font-weight: 500; letter-spacing: -.01em; }
.dlg .sub { font-size: 12px; color: var(--faint); margin-top: 4px; }
#addFields { display: flex; flex-direction: column; gap: 18px; }
.field { display: flex; flex-direction: column; gap: 9px; }
.field .subtle { margin-top: -2px; text-wrap: pretty; }
/* time worked: whole hours, then a select of minutes in steps of 5 (log.jte) */
.hm { display: flex; align-items: center; gap: 8px; }
.hm span { color: var(--muted); font-size: 14px; }
.hm input[type="number"] { width: 96px; flex: 0 0 auto; }
.hm select { width: 96px; flex: 0 0 auto; height: 54px; font-size: 20px; color-scheme: dark; }
.field .choices { gap: 6px; }
.field .choices .kid { display: flex; align-items: center; gap: 10px; cursor: pointer; border: 1px solid var(--line2); }
.field .choices .kid:hover { border-color: var(--line3); }
.field .choices input { accent-color: #e0a355; width: 16px; height: 16px; flex-shrink: 0; }
.field > label { font-size: 12px; color: var(--muted); }
.seg { display: flex; gap: 8px; }
.seg button { flex-grow: 1; min-height: 46px; border-radius: 10px; border: 1px solid var(--line2); color: var(--muted); transition: border-color .15s, background .15s, color .15s; }
.seg button[aria-pressed="true"] {
  border-color: rgba(242,201,138,.55); background: rgba(224,163,85,.09); color: var(--amber-2); font-weight: 500;
  box-shadow: 0 0 18px rgba(224,163,85,.12);
}
.dlgfoot { display: flex; gap: 8px; }
.dlgfoot button { flex-grow: 1; min-height: 46px; border-radius: 10px; border: 1px solid var(--line3); font-weight: 500; color: var(--ink2); }
.dlgfoot button.save {
  background: linear-gradient(180deg, #f6d9a6, #e0a355); border-color: #f2c98a; color: #14110a; font-weight: 600;
  box-shadow: 0 0 0 1px rgba(242,201,138,.3), 0 0 28px rgba(224,163,85,.3);
}
.choices { display: flex; flex-direction: column; gap: 8px; }
.choices button { min-height: 46px; border-radius: 10px; border: 1px solid var(--line3); text-align: left; padding: 0 14px; color: var(--ink2); }
.choices button:hover { background: var(--raise); color: var(--ink); }
.choices button.danger { color: var(--muted); }
input[type="text"], input[type="date"], select {
  width: 100%; min-height: 44px; padding: 0 12px; border-radius: 10px;
  background: var(--ground); border: 1px solid var(--line3); color: var(--ink); font: inherit;
}

@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

/* First run without JavaScript (build-order 7b): plain forms in the sign-in card's
   style. The landing page's scene goes over the top of these later. */
.frbox { width: min(760px, 100%); }
.frwords { display: flex; flex-wrap: wrap; gap: 8px; }
.frword { position: relative; }
/* the checkbox stays in the page for the keyboard and screen readers; the pill is what shows */
.frword input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.frword span {
  display: inline-block; padding: 7px 14px; border-radius: 16px; cursor: pointer;
  border: 1px solid var(--line3); color: var(--muted); transition: color .15s, border-color .15s, background .15s;
}
.frword span:hover { color: var(--ink2); }
.frword input:checked + span { color: var(--ink); border-color: rgba(242,201,138,.6); background: rgba(224,163,85,.12); }
.frword input:focus-visible + span { outline: 2px solid var(--blue); outline-offset: 2px; }
.frown { display: flex; gap: 8px; }
.frown .btn { min-height: 44px; }
.frcards { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.frcard { padding: 16px; gap: 10px; }
.frcard label { font-weight: 600; color: var(--ink); }
.frcard textarea {
  width: 100%; resize: vertical; padding: 10px 12px; border-radius: 10px; font: inherit;
  background: var(--ground); border: 1px solid var(--line3); color: var(--ink);
}
.fracts { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.fracts .btn { min-height: 44px; }
.fracts .go { width: auto; padding: 0 24px; }
/* first run's plain form has no app shell, so its sign-out sits under the card, low-key */
.frout {
  align-self: center; padding: 0;
  font-size: 11px; color: var(--dim); border-bottom: 1px dotted var(--line3);
}
.frout:hover { color: var(--muted); }

/* Not in the prototype: the admin's requests page (build-order 7a). */
.reqs { display: flex; flex-direction: column; }
.req { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 12px 0; }
.req + .req { border-top: 1px solid var(--line2); }
.req .nm { font-size: 13px; color: var(--ink); }
.req .sub { font-size: 11.5px; color: var(--dim); margin-top: 3px; }
.req .acts { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; }
.reqfull { margin: 0; font-size: 12px; color: var(--amber-2); }
.reqstate { font-size: 12px; color: var(--muted); }
.reqstate.warn { color: var(--amber-2); }
.linkbox {
  width: 100%; min-height: 40px; padding: 0 12px; border-radius: 9px; font-size: 12px;
  background: var(--ground); border: 1px solid var(--line3); color: var(--ink);
}

/* ---- narrow ---- */
@media (max-width: 900px) {
  .req .btn { min-height: 44px; }
  .rail { display: none; }
  .viewnav { display: flex; }
  .topbar { padding: 10px 16px 0; }
  .topbar .brand { display: flex; }
  .topbar .btn { min-height: 36px; }
  .split { grid-template-columns: 1fr; }
  .board { grid-template-columns: 1fr; padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px)); }
  .col { display: none; }
  .col.shown { display: flex; }
  .tabs.on { display: flex; }
  .bar { padding: 10px 16px; }
  .filter { order: 3; flex-basis: 100%; margin-left: 0; }
  .filter select { flex: 1 1 0; max-width: none; min-height: 40px; }
  .page { padding: 16px 16px calc(24px + env(safe-area-inset-bottom, 0px)); }
  .card { padding: 12px 14px; }
  .card .title { font-size: 15px; }
  .pagehead .hint { display: none; }   /* a note about how to read the page, not the page */
  .kids { margin: 0 -6px; }
}

/* Not in the prototype: the move form on each card (build-order step 5). It is
   the version that works with JavaScript off; drag and drop layers over it later. */
.cardfoot select {
  flex-grow: 1; min-width: 0; min-height: 36px; padding: 0 8px; border-radius: 8px;
  border: 1px solid var(--line2); background: var(--panel2); color: var(--ink2); font: inherit; font-size: 12px;
}
.cardfoot button[type="submit"] { flex-grow: 0; padding: 0 14px; }

/* Not in the prototype: the log page (build-order step 6). The prototype logs time
   in a JavaScript dialog with a stepper and buttons; this is the page that works
   without JavaScript, made to look like that dialog. */
.logpage {
  margin: 20px auto 0; width: min(420px, 100%);
  border: 1px solid var(--line3); border-radius: 14px; background: var(--panel);
  box-shadow: 0 1px 0 rgba(255,255,255,.04) inset, 0 -20px 60px rgba(224,163,85,.06), 0 30px 80px rgba(0,0,0,.6);
}
.logpage input[type="number"], .logpage input[type="date"] {
  height: 54px; padding: 0 14px; border-radius: 10px; border: 1px solid var(--line3);
  background: var(--ground); color: var(--ink); font: inherit; font-size: 20px; color-scheme: dark;
}
/* effort: radio buttons that look like the prototype's segmented buttons */
.seg label { flex-grow: 1; display: flex; }
.seg input { position: absolute; opacity: 0; pointer-events: none; }
.seg span {
  flex-grow: 1; min-height: 46px; display: flex; align-items: center; justify-content: center;
  border-radius: 10px; border: 1px solid var(--line2); color: var(--muted); cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.seg input:checked + span {
  border-color: rgba(242,201,138,.55); background: rgba(224,163,85,.09); color: var(--amber-2); font-weight: 500;
  box-shadow: 0 0 18px rgba(224,163,85,.12);
}
.seg input:focus-visible + span { outline: 2px solid var(--blue); outline-offset: 2px; }
.dlgfoot a {
  flex-grow: 1; min-height: 46px; display: flex; align-items: center; justify-content: center;
  border-radius: 10px; border: 1px solid var(--line3); font-weight: 500; color: var(--ink2); text-decoration: none;
}

/* Not in the prototype: quick capture without JavaScript (build-order 7d), on the
   log page's card. The kind links stand in for the dialog's switch. */
.kinds { display: flex; gap: 6px; flex-wrap: wrap; }
.kinds a {
  padding: 6px 13px; border-radius: 16px; border: 1px solid var(--line2);
  font-size: 13px; color: var(--muted); text-decoration: none;
}
.kinds a[aria-current="page"] { background: var(--raise2); border-color: var(--line3); color: var(--ink); font-weight: 500; }
.dlg .sub a { color: var(--amber-2); }
label.standing { display: flex; gap: 10px; align-items: flex-start; font-size: 12px; color: var(--muted); cursor: pointer; }
label.standing input { accent-color: #e0a355; width: 16px; height: 16px; margin: 1px 0 0; flex-shrink: 0; }
.bar .newtask { text-decoration: none; }

/* Not in the prototype: the day page (build-order 9.2), on the log page's card. */
.daylink { font-size: 12px; color: var(--dim); text-decoration: none; }
.daylink:hover { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.daynav { display: flex; justify-content: space-between; margin-top: 8px; font-size: 12px; }
.daynav a { color: var(--muted); text-decoration: none; }
.daynav a:hover { color: var(--ink2); }
.daysessions { display: flex; flex-direction: column; margin-top: 8px; }
.daysession { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 8px 0; }
.daysession + .daysession { border-top: 1px solid var(--line2); }
.daysession .ctx { font-size: 11px; color: var(--faint); margin-bottom: 2px; }
.daysession .fig { flex-shrink: 0; font-size: 12px; color: var(--muted); }
.dayform { display: flex; flex-direction: column; gap: 20px; }
/* straight after a save: says what was saved, where the button alone only changed its label */
.dayform .saved {
  margin: 0; padding: 10px 12px; border-radius: 10px; font-size: 13px; color: var(--amber-2);
  border: 1px solid rgba(242,201,138,.35); background: rgba(224,163,85,.08);
}

/* ---- sign in, ask to join, accept an invite (build-order 7a) ----
   From the prototype's sign-in block. Left out: the rules that only existed for
   its JavaScript to switch screens ([hidden] toggles, hiding #shell), and the
   password-strength meter, which needs JavaScript and wasn't added to the accept
   page. */

/* The app's body never scrolls (the board scrolls inside its columns). A signed-out
   page is one card, and on a short phone screen it must be able to scroll. */
body.signedout { height: auto; overflow: auto; }

#auth {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 32px 20px calc(48px + env(safe-area-inset-bottom, 0px));
  background:
    radial-gradient(60% 420px at 50% 8%, rgba(224,163,85,.10), rgba(224,163,85,0) 70%),
    var(--ground);
}
.authbox { width: min(380px, 100%); display: flex; flex-direction: column; gap: 22px; }
.authmark {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  font-size: 16px; font-weight: 600; letter-spacing: -.012em;
}
a.authmark { color: inherit; text-decoration: none; }   /* back to the landing page */
.authmark .dot {
  width: 20px; height: 20px; border-radius: 7px;
  background: radial-gradient(circle at 50% 45%, #fff2d8 0, #f2c98a 22%, #e0a355 48%, #6a4212 100%);
  box-shadow: 0 0 18px rgba(224,163,85,.55), inset 0 0 0 1px rgba(255,255,255,.08);
}
.authcard {
  display: flex; flex-direction: column; gap: 16px;
  background: var(--panel); border: 1px solid var(--line2); border-radius: 14px;
  padding: 24px 22px;
  box-shadow: 0 1px 0 rgba(255,255,255,.03) inset, 0 -18px 50px rgba(224,163,85,.05), 0 24px 60px rgba(0,0,0,.5);
}
.authcard h1 {
  margin: 0; font-size: 21px; font-weight: 600; letter-spacing: -.02em;
  background: linear-gradient(180deg, #ffffff 0%, #dfe4ec 55%, #aab3c0 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.authcard .sub { margin: -8px 0 4px; font-size: 12.5px; color: var(--faint); text-wrap: pretty; }
.authcard .sub b { color: var(--ink2); font-weight: 500; }
.authcard input[type="email"], .authcard input[type="password"], .authcard input[type="text"] {
  width: 100%; min-height: 44px; padding: 0 12px; border-radius: 10px;
  background: var(--ground); border: 1px solid var(--line3); color: var(--ink); font: inherit;
}
.authcard input:focus {
  outline: 0; border-color: rgba(242,201,138,.5);
  box-shadow: 0 0 0 1px rgba(242,201,138,.16), 0 0 26px rgba(224,163,85,.16);
}
/* the amber pill lives in the first-run stylesheet, which is scoped to
   #firstrun, so the auth card carries its own */
.authcard .go, .fracts .go {
  width: 100%; min-height: 46px; border-radius: 10px; font-size: 15px; font-weight: 600;
  background: linear-gradient(180deg, #f6d9a6, #e0a355);
  border: 1px solid #f2c98a; color: #14110a;
  box-shadow: 0 0 0 1px rgba(242,201,138,.3), 0 0 30px rgba(224,163,85,.3);
  transition: box-shadow .18s, transform .18s;
}
.authcard .go:hover, .fracts .go:hover { transform: translateY(-1px); box-shadow: 0 0 0 1px rgba(242,201,138,.5), 0 0 40px rgba(224,163,85,.4); }
.authcard .go[disabled] { opacity: .45; transform: none; }
.authfoot { margin: 2px 0 0; font-size: 11.5px; color: var(--dim); line-height: 1.5; text-wrap: pretty; }

.autherr {
  margin: 0; padding: 9px 12px; border-radius: 9px; font-size: 12.5px;
  color: var(--amber-2); background: rgba(224,163,85,.09);
  border: 1px solid rgba(242,201,138,.35);
}
/* The join form's bot trap. Off screen rather than display:none, which some bots
   check for; it overlaps nothing, so it can't swallow a click either. */
.trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
/* not in the prototype, which had no links on its cards: keep them in the warm accent */
.authcard a { color: var(--amber-2); text-decoration: underline; text-underline-offset: 2px; }

/* the running version, in the bottom-right corner of every page (version.jte) */
.version {
  flex-shrink: 0; text-align: right;
  padding: 2px calc(12px + env(safe-area-inset-right, 0px)) calc(4px + env(safe-area-inset-bottom, 0px));
  font-size: 10.5px; color: var(--dim);
}


/* Not in the prototype: the forecast (build-order 9.19). Its two tables share a
   panel, the days and then the tasks, with a gap between them. */
.forecastdays + .forecasttasks, .panel .empty + .forecasttasks { margin-top: 18px; }
.forecastdays td > div + div { margin-top: 4px; }
/* on a phone, a date or a figure wraps whole rather than leaving its unit on the next line */
.forecastdays .num, .forecasttasks .num { white-space: nowrap; }
.forecasttasks + .subtle { margin-top: 10px; }
