:root{
  --ground:#fff; --ink:#111; --body:#222; --muted:#6b6b6b; --faint:#8c8c8c;
  --rule:#e4e4e4; --rule-strong:#b4b4b4; --sunk:#f2f2f2;
  color-scheme:light;
}
*{box-sizing:border-box}
body{margin:0;background:var(--ground);color:var(--body);
  font-family:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased}
.wrap{max-width:1180px;margin:0 auto;padding:26px 24px 96px}

h1{margin:0 0 18px;color:var(--ink);font-size:1.85rem;font-weight:650;
  letter-spacing:-.021em;line-height:1.12}
h2{margin:38px 0 12px;color:var(--ink);font-size:1.12rem;font-weight:600;letter-spacing:-.011em}
h3{margin:26px 0 8px;color:var(--ink);font-size:.95rem;font-weight:600}
p{margin:0 0 12px}
code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.9em}
a{color:inherit;text-decoration:underline;text-underline-offset:2px;
  text-decoration-color:var(--rule-strong)}
a:hover{text-decoration-color:var(--ink)}

nav.top{display:flex;flex-wrap:wrap;gap:20px;margin:0 0 30px;padding-bottom:13px;
  border-bottom:1px solid var(--rule);font-size:.76rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted)}
nav.top a{text-decoration:none}
nav.top a:hover{color:var(--ink)}
nav.top a.here{color:var(--ink);font-weight:650}

.scroll{overflow-x:auto;margin-bottom:10px}
/* Sized to its contents, not stretched to the page: a table forced to 100%
   spreads five columns across a screen and puts a hand's width between a name
   and the number that belongs to it. */
table{border-collapse:collapse;width:auto;max-width:100%;font-size:.85rem}
th,td{text-align:left;padding:4px 9px;border:1px solid var(--rule-strong);vertical-align:top}
/* Headings are set small and filled rather than shouted in capitals: capitals
   are wider, and the width was the problem. */
thead th{background:var(--sunk);color:var(--ink);font-size:.74rem;font-weight:650;
  white-space:nowrap;border-bottom:2px solid var(--ink)}
tbody th{color:var(--ink);font-weight:600;white-space:nowrap}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
tfoot td{border-top:2px solid var(--ink);color:var(--ink);font-weight:650}
tfoot td.num{font-weight:650}

input,select,button,textarea{font:inherit;color:inherit}
input[type=checkbox]{accent-color:var(--ink)}
input[type=text],input[type=time],input[type=password],input[type=file],select{
  background:#fff;border:1px solid var(--rule-strong);border-radius:2px;padding:2px 6px}
input:focus-visible,select:focus-visible,button:focus-visible{
  outline:2px solid var(--ink);outline-offset:1px}
button{background:#fff;border:1px solid var(--ink);border-radius:2px;color:var(--ink);
  padding:5px 12px;cursor:pointer}
button:hover{background:var(--ink);color:#fff}
label{display:inline-block}
td form{display:block;margin:3px 0 0}
td button{padding:1px 7px;font-size:.76rem}
td form{margin:2px 0 0}

.periodnav{display:flex;gap:16px;align-items:baseline;margin:0 0 6px;color:var(--muted);
  font-size:.85rem}
.periodnav strong{color:var(--ink);font-weight:600}
/* Stacked, not paired: with a column per day a sheet is too wide to share a
   screen with the other one, and a squeezed pair reads worse than two. */
.sheets{display:grid;grid-template-columns:1fr;gap:30px;margin-top:20px}
.sheet h2{margin-top:0}
/* A pay sheet is read across the row. Wrapping a name or an occupation over
   two lines to save width costs more than the width was worth, so the columns
   hold their line and the sheet scrolls if it must. */
.sheet th,.sheet td,.tight th,.tight td{white-space:nowrap}
.total{margin:26px 0 0;color:var(--ink);font-weight:600}
.empty{color:var(--muted)}
.hint{color:var(--muted);font-size:.86rem;max-width:70ch}

/* A section with a list down the left and the work on the right. minmax(0,1fr)
   so a wide table scrolls inside its own column instead of stretching the
   grid and pushing the list off the screen. */
.shell{display:grid;grid-template-columns:172px minmax(0,1fr);gap:34px;align-items:start}
.side{display:flex;flex-direction:column;gap:1px;border-right:1px solid var(--rule);
  padding-right:16px}
.side a{text-decoration:none;color:var(--muted);font-size:.9rem;padding:5px 8px;border-radius:2px}
.side a:hover{color:var(--ink);background:var(--sunk)}
.side a.here{color:var(--ink);font-weight:600;background:var(--sunk)}
.work{min-width:0}
.work > h2:first-child{margin-top:0}

details{margin-top:40px;border-top:1px solid var(--rule);padding-top:14px}
details h3:first-of-type{margin-top:0}
summary{cursor:pointer;color:var(--muted);font-size:.76rem;letter-spacing:.09em;
  text-transform:uppercase}
summary:hover{color:var(--ink)}
details[open] summary{margin-bottom:16px}


/* The week line: where you are, how to move, and the filter handle. */
.weeknav{display:flex;flex-wrap:wrap;gap:16px;align-items:center;margin:0 0 16px;
  color:var(--muted);font-size:.85rem}
.weeknav strong{color:var(--ink);font-weight:600}
.weeknav .gap{margin-left:auto}

/* One button per cell: an outline that reads as an affordance, not a word. */
button.plus{padding:1px 8px;font-size:.85rem;line-height:1.35}

/* The filter handle: an icon, and nothing else.
   It is a <select>, which is the one control that hands its popup to the
   operating system to draw — so the menu that opens is the real thing, with
   the platform's own type, spacing and keyboard behaviour, not a list styled
   to resemble one. The closed control is shrunk to the funnel; only its own
   chrome is styled, never the menu. */
.funnelwrap{position:relative;display:inline-block;line-height:0}
select.funnel{appearance:none;-webkit-appearance:none;width:31px;height:27px;
  padding:0;margin:0;border:1px solid var(--rule-strong);border-radius:3px;
  color:transparent;font-size:0;cursor:pointer;
  background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23666' d='M1.4 2.6h13.2L9.2 8.9v4.8L6.8 12.2V8.9z'/%3E%3C/svg%3E") center/13px no-repeat}
select.funnel:hover{border-color:var(--ink)}
/* The options are the system's to draw; they only need a colour to inherit. */
select.funnel option,select.funnel optgroup{color:var(--ink);font-size:13px}
.funnelwrap.on select.funnel{border-color:var(--ink)}
/* Filters that are on but out of sight are a trap, so the icon says so. */
.funnelwrap.on::after{content:"";position:absolute;top:-2px;right:-2px;
  width:6px;height:6px;border-radius:50%;background:#2764e0;
  box-shadow:0 0 0 1.5px var(--ground)}

/* The add menu: a context menu, drawn where the cursor is.
   Still a native <dialog> underneath — showModal() is what gives us Escape,
   the focus trap and a click-anywhere-else that dismisses, none of which is
   worth hand-rolling. The backdrop is made invisible rather than removed,
   because it is the thing catching that outside click. */
dialog.menu{position:fixed;margin:0;padding:4px;border:1px solid rgba(0,0,0,.16);
  border-radius:7px;background:#fff;color:var(--ink);
  box-shadow:0 8px 26px rgba(0,0,0,.19),0 1px 2px rgba(0,0,0,.10);
  font-size:.82rem;overflow:visible}
dialog.menu::backdrop{background:transparent}
.menu .when{margin:2px 9px 5px;color:var(--faint);font-size:.7rem;
  letter-spacing:.06em;text-transform:uppercase}
.menu ul{list-style:none;margin:0;padding:0;min-width:154px}
.menu li{position:relative}
/* Rows, not buttons: no border, no box, and the pointer stays an arrow, which
   is what every menu on the machine already does. */
.menu button{display:block;width:100%;text-align:left;background:none;border:0;
  border-radius:4px;padding:4px 24px 4px 9px;color:inherit;font-size:inherit;
  white-space:nowrap;cursor:default}
/* The whole row highlights, and stays highlighted while its submenu is open. */
.menu li:hover > button,.menu li:focus-within > button{background:#2764e0;color:#fff;
  outline:none}
.menu li.has > button::after{content:"\203A";position:absolute;right:9px;
  font-size:1.05em;line-height:1}
.menu li ul{display:none;position:absolute;left:100%;top:-5px;padding:4px;
  max-height:62vh;overflow-y:auto;
  background:#fff;border:1px solid rgba(0,0,0,.16);border-radius:7px;
  box-shadow:0 8px 26px rgba(0,0,0,.19),0 1px 2px rgba(0,0,0,.10)}
/* Hover opens it; focus-within is the same door for a keyboard. */
.menu li:hover > ul,.menu li:focus-within > ul{display:block}
/* Near the right edge the submenu opens back over its parent instead of off
   the screen — Sunday is the last column, and it is always near the edge. */
.menu.flip li ul{left:auto;right:100%}

/* The other kind of dialog: a form, centred, over a dimmed page. A menu is a
   glance and belongs at the cursor; filling this one in is a job, and a job
   deserves the whole screen's attention. */
dialog.modal{margin:auto;border:1px solid var(--rule-strong);border-radius:6px;
  padding:26px 28px;background:var(--ground);color:var(--body);
  width:min(430px,calc(100vw - 32px));max-height:calc(100vh - 48px);
  box-shadow:0 18px 50px rgba(0,0,0,.22)}
dialog.modal::backdrop{background:rgba(17,17,17,.38)}
.modal h3{margin:0 0 18px}
.modal p{margin:0 0 13px}
.modal p:last-child{margin:14px 0 0}
.modal label{font-size:.74rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.modal select,.modal input[type=text],.modal input[type=time],.modal input[type=number]{
  display:block;margin-top:3px;width:100%}
/* The two ends of a window, side by side, because that is how it is read. */
.pair{display:flex;gap:12px}
.pair label{flex:1}

@media (max-width:820px){
  .shell{grid-template-columns:1fr;gap:20px}
  .side{flex-direction:row;flex-wrap:wrap;border-right:0;
    border-bottom:1px solid var(--rule);padding:0 0 12px}
}
@media print{
  nav.top,form,details,.periodnav a{display:none}
  body{font-size:11pt}
  .wrap{max-width:none;padding:0}
}
