/* Today's Five v4 — all colour/type tokens come from #theme-vars (theme.js). */

/* ---------------- fonts: self-hosted, latin subset, only the weights the pairs use (see fonts/README.md) ---------------- */
@font-face{font-family:"Lato";font-style:normal;font-weight:400;font-display:swap;src:url(fonts/lato-400.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Lato";font-style:normal;font-weight:700;font-display:swap;src:url(fonts/lato-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Lato";font-style:normal;font-weight:900;font-display:swap;src:url(fonts/lato-900.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"PT Sans";font-style:normal;font-weight:400;font-display:swap;src:url(fonts/pt-sans-400.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"PT Sans";font-style:normal;font-weight:700;font-display:swap;src:url(fonts/pt-sans-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Fraunces";font-style:normal;font-weight:500 700;font-display:swap;src:url(fonts/fraunces-500-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Quicksand";font-style:normal;font-weight:500 700;font-display:swap;src:url(fonts/quicksand-500-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Space Grotesk";font-style:normal;font-weight:500 700;font-display:swap;src:url(fonts/space-grotesk-500-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:400 600;font-display:swap;src:url(fonts/ibm-plex-sans-400-600.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Playfair Display";font-style:normal;font-weight:700 800;font-display:swap;src:url(fonts/playfair-display-700-800.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Source Serif 4";font-style:normal;font-weight:400 600;font-display:swap;src:url(fonts/source-serif-4-400-600.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Manrope";font-style:normal;font-weight:500 800;font-display:swap;src:url(fonts/manrope-500-800.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"DM Serif Display";font-style:normal;font-weight:400;font-display:swap;src:url(fonts/dm-serif-display-400.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"DM Sans";font-style:normal;font-weight:400 700;font-display:swap;src:url(fonts/dm-sans-400-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Outfit";font-style:normal;font-weight:500 800;font-display:swap;src:url(fonts/outfit-500-800.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Nunito Sans";font-style:normal;font-weight:400 700;font-display:swap;src:url(fonts/nunito-sans-400-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:500 800;font-display:swap;src:url(fonts/jetbrains-mono-500-800.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url(fonts/ibm-plex-mono-400.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:600;font-display:swap;src:url(fonts/ibm-plex-mono-600.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Cormorant Garamond";font-style:normal;font-weight:600 700;font-display:swap;src:url(fonts/cormorant-garamond-600-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Josefin Sans";font-style:normal;font-weight:400 700;font-display:swap;src:url(fonts/josefin-sans-400-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Archivo";font-style:normal;font-weight:500 800;font-display:swap;src:url(fonts/archivo-500-800.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Lora";font-style:normal;font-weight:500 700;font-display:swap;src:url(fonts/lora-500-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Karla";font-style:normal;font-weight:400 700;font-display:swap;src:url(fonts/karla-400-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Fredoka";font-style:normal;font-weight:500 700;font-display:swap;src:url(fonts/fredoka-500-700.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Baloo 2";font-style:normal;font-weight:500 800;font-display:swap;src:url(fonts/baloo-2-500-800.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}


*{box-sizing:border-box;margin:0;padding:0}
html{height:100%}
body{
  margin:0;background:var(--ink);color:var(--text);
  font-family:var(--font-task);-webkit-font-smoothing:antialiased;
  overflow:hidden;height:100%;
  -webkit-tap-highlight-color:transparent;
}
button{font:inherit;color:inherit}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
#list-h1{font-family:var(--font-ui);font-weight:700} /* the hidden heading is laid out: in the row font it would pull Lato 700 in at first paint */
[hidden]{display:none !important}

/* ---------------- atmosphere ---------------- */
#glow{position:fixed;inset:0;pointer-events:none;z-index:0;background:var(--glow);opacity:.62;transition:opacity .85s ease}
#glow.flare{opacity:1;transition:opacity .22s ease}
#fx{position:fixed;inset:0;pointer-events:none;z-index:60}
/* a kit may carry a background layer in #field; its rules come with secretfx.js (secretfx.css), not with this file */
/* ---------------- shell ---------------- */
#shell{
  position:relative;z-index:2;height:100vh;height:100dvh;
  display:flex;flex-direction:column;
  padding:calc(clamp(.9rem,2.2vh,1.6rem) + env(safe-area-inset-top,0px)) calc(clamp(1rem,4vw,3.4rem) + env(safe-area-inset-right,0px)) calc(7px + env(safe-area-inset-bottom,0px)) calc(clamp(1rem,4vw,3.4rem) + env(safe-area-inset-left,0px));
}

/* 1.12 b403: a kitchen display (kitchen.js) shows nothing until its first fit, or the type would show at its everyday
   size for a frame and then jump; its own rules come with kitchen.css */
html.kitchen:not(.k-ready) #shell{visibility:hidden}

/* ---------------- rail ---------------- */
.rail{
  flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;gap:1rem;
  font-family:var(--font-ui);font-weight:700;font-size:clamp(9.5px,1.05vw,12px);
  letter-spacing:.15em;text-transform:uppercase;color:var(--dim);
  padding-bottom:clamp(.7rem,1.8vh,1.3rem);border-bottom:1px solid var(--hair);
  min-height:44px;
}
.rail-l,.rail-r{display:flex;align-items:center;gap:clamp(.4rem,1.2vw,.85rem);min-width:0}
.rail-r .tools{display:flex;align-items:center;gap:clamp(.4rem,1.2vw,.85rem)} /* 1.9: the same gap as the rail, so nothing moves (proposal 27) */
.rail-l{flex:1 1 auto}
#date{white-space:nowrap}
#count,#shuffle{color:var(--muted);font-variant-numeric:tabular-nums;letter-spacing:.09em;white-space:nowrap;background:transparent;border:0;padding:.3em .2em;font:inherit;letter-spacing:.09em;text-transform:inherit;cursor:pointer;min-height:32px;border-radius:999px}
#count b{color:var(--accent-text);font-weight:700;display:inline-block;clip-path:inset(0 -.3em)} /* 1.12 b293: the odometer's window */
#count b i{display:inline-block;font-style:normal;position:relative}
#count b i[data-was]::before{content:attr(data-was);position:absolute;left:0;top:-100%} /* the old number, riding along */
#count b i.down[data-was]::before{top:100%}
#count:focus-visible,#shuffle:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
#count[aria-pressed="true"]{color:var(--accent-text)}

.chip{
  font:inherit;letter-spacing:inherit;text-transform:inherit;
  background:transparent;color:var(--dim);border:1px solid var(--hair);border-radius:999px;
  padding:.45em .85em;cursor:pointer;white-space:nowrap;min-height:32px;
  transition:color .18s ease,border-color .18s ease,background-color .18s ease;
}
.chip:hover{color:var(--text);border-color:var(--hair-hi);background:var(--ink-2)}
.chip:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.chip[aria-pressed="true"]{color:var(--accent-text);border-color:var(--accent)}
.chip.accent{color:var(--accent-text);border-color:var(--hair-hi)}
.chip.plain{border-color:transparent;padding-left:.4em;padding-right:.4em}
.chip.icon{padding:.45em .7em;font-size:1.15em;line-height:1;letter-spacing:0}
#listname{color:var(--muted);max-width:14em;overflow:hidden;text-overflow:ellipsis}
.pill{font:inherit;letter-spacing:.12em;text-transform:uppercase;color:var(--accent-text);padding:.35em .2em;white-space:nowrap;opacity:.9}
.fine{font-size:12px;color:var(--muted)}
.fine a{color:var(--muted)}
.fine a:hover{color:var(--text)}

/* view toggle */
.seg{display:inline-flex;border:1px solid var(--hair);border-radius:999px;overflow:hidden}
.seg button{
  font:inherit;letter-spacing:inherit;text-transform:inherit;color:var(--dim);
  background:transparent;border:0;padding:.45em .85em;cursor:pointer;min-height:32px;
  transition:color .18s ease,background-color .18s ease;
}
.seg button+button{border-left:0}
.seg button{border-radius:999px} /* 1.12 b293: the chosen view is a pill the tabs slide across (panels.css) */
.seg button:hover{color:var(--text);background:var(--ink-2)}
.seg button[aria-selected="true"]{color:var(--accent-text);background:var(--ink-2)}
.seg button:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}

/* sync dot */
.dot{
  display:inline-flex;align-items:center;gap:.5em;white-space:nowrap;
  font:inherit;font-size:.92em;letter-spacing:.12em;text-transform:inherit;color:var(--dim);cursor:default;
  background:transparent;border:0;padding:.3em .2em;min-height:32px;
}
.dot:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:999px}
.dot{position:relative}
.dot .lock{position:absolute;left:calc(.2em - 3px);top:50%;width:12px;height:12px;margin-top:-6px;opacity:0;fill:none;stroke:var(--accent);stroke-width:1.8;stroke-linecap:round;overflow:visible;pointer-events:none} /* 1.12 b293: the unseal's */
.dot .lock .shackle{transform-box:fill-box;transform-origin:100% 100%}
.dot::before{
  content:"";width:6px;height:6px;border-radius:50%;
  background:var(--accent);box-shadow:0 0 0 0 var(--accent);
  transition:background-color .3s ease,box-shadow .3s ease,opacity .3s ease;
}
.dot .lbl{display:none}
.dot[data-s="syncing"]::before{animation:pulse 1.1s ease-in-out infinite}
.dot[data-s="offline"]::before{background:transparent;box-shadow:inset 0 0 0 1.5px var(--dim)}
.dot[data-s="error"]::before{background:var(--danger)}
.dot[data-s="gone"]::before{background:var(--danger)}
.dot[data-s="off"]::before{background:transparent;box-shadow:inset 0 0 0 1.5px var(--dim);opacity:.7}
.dot[data-s="off"] .lbl,.dot[data-s="gone"] .lbl,.dot[data-s="busy"] .lbl,.dot[data-s="full"] .lbl,.dot[data-s="toolarge"] .lbl,.dot[data-s="readonly"] .lbl,.dot[data-s="unreadable"] .lbl,.dot[data-s="offline"] .lbl,.dot[data-s="error"] .lbl{display:inline}
.dot[data-s="busy"]::before,.dot[data-s="full"]::before,.dot[data-s="toolarge"]::before,.dot[data-s="readonly"]::before,.dot[data-s="unreadable"]::before{background:var(--danger)}
.dot[data-s="synced"][data-live="0"]::before{background:transparent;box-shadow:inset 0 0 0 2px var(--accent)}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}

/* ---------------- main ---------------- */
#main{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;justify-content:center;padding:clamp(.4rem,1.8vh,1.3rem) 0;position:relative}
.view{display:flex;flex-direction:column;min-height:0;max-height:100%}

/* ---------------- today ---------------- */
#list:focus{outline:none} /* 1.7: the save sheet hands focus to the list itself; the next Tab is the first line */
#list{
  list-style:none;display:flex;flex-direction:column;
  max-height:100%;overflow-y:auto;overscroll-behavior:contain;
  scrollbar-width:thin;scrollbar-color:var(--ink-3) transparent;
  --unit:7.4vh;
}
#list[data-count="6"]{--unit:6.4vh}
#list[data-count="7"]{--unit:5.7vh}
#list[data-count="8"]{--unit:5.1vh}

.row{
  position:relative;display:flex;align-items:flex-start;gap:.46em;
  width:100%;text-align:left;
  font-family:var(--font-task);
  font-size:clamp(1.45rem,min(5.5vw,var(--unit)),4.7rem);
  font-weight:var(--task-w);letter-spacing:var(--task-ls);line-height:var(--task-lh);
  color:var(--text);border-radius:.16em;
  padding:.32em .3em .32em .26em;
  -webkit-touch-callout:none;user-select:none;-webkit-user-select:none;
  touch-action:pan-y;
  transition:background-color .2s ease,color .3s ease .1s;
}
.row:hover{background:var(--ink-2)}
.no-hover .row:hover{background:transparent} /* 1.7: a row that slid under a still cursor is not hovered */
.no-hover .row:hover .box{border-color:var(--hair-solid)}
.row.done{color:var(--done)}
.row.editing{background:transparent}
.row.editing:hover{background:transparent}

.check{
  display:flex;align-items:flex-start;gap:.46em;flex:1 1 auto;min-width:0;
  background:transparent;border:0;text-align:left;cursor:pointer;
  font:inherit;letter-spacing:inherit;line-height:inherit;color:inherit;padding:0;
}
.check:focus-visible{outline:2px solid var(--accent);outline-offset:4px;border-radius:.12em}
.tx{min-width:0;overflow-wrap:anywhere}
.cap{
  display:inline-block;vertical-align:middle;margin-left:.6em;
  font-family:var(--font-ui);font-weight:700;font-size:clamp(9px,.28em,13px);
  letter-spacing:.16em;text-transform:uppercase;color:var(--dim);
  transform:translateY(-.15em);
}
.note{
  display:block;font-family:var(--font-ui);font-weight:400;font-size:clamp(11px,.34em,15px);
  letter-spacing:.02em;text-transform:none;color:var(--muted);line-height:1.35;margin-top:.15em;
}
#list .note{display:block}

/* checkbox */
.box{
  flex:0 0 auto;width:.66em;height:.66em;margin-top:.24em;
  border:.055em solid var(--hair-solid);border-radius:.11em;
  display:grid;place-items:center;
  transition:border-color .3s ease,background-color .3s ease;
}
.row:hover .box{border-color:var(--accent)}
.row.done .box{border-color:var(--accent);background:var(--box-done-bg)}
.box svg{width:74%;height:74%;overflow:visible}
.box path{
  fill:none;stroke:var(--ink);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:26;stroke-dashoffset:26;
  transition:stroke-dashoffset .3s cubic-bezier(.22,1,.36,1) .12s;
}
.row.done .box path{stroke-dashoffset:0}

/* strike: one measured overlay per rendered line (see layoutStrikes) */
.lines{position:absolute;inset:0;pointer-events:none}
.ghost,.ink{position:absolute;height:max(3px,.058em);border-radius:999px;transform-origin:left center}
.ghost{background:var(--accent);opacity:0;transition:opacity .17s ease}
.row:hover:not(.done):not(.editing) .ghost{opacity:.22}
.ink{
  background:var(--strike-bg);background-size:var(--strike-size);
  box-shadow:var(--strike-shadow);
  transform:scaleX(0);
  transition:transform var(--t,.22s) var(--e,cubic-bezier(.16,1,.3,1)) var(--d,0s); /* 1.9: the ink lands inside the knock's decay (it was .38s, 270 ms of silent drawing after a 108 ms sound); 1.12 b279: a wrapped line's strike is one stroke, --t/--e/--d per line (layoutStrikes) */
}
.row:not(.done) .ink{transition-delay:var(--dr,0s)} /* 1.12 b279: unchecking unwinds the stroke, last line first */
/* a strike that moves animates background-position, which the compositor cannot take, so it runs on struck rows
   only: an overlay at scaleX(0) was invisible and cost the same (DECISIONS.md, "The sparkle field") */
.row.done .ink{transform:scaleX(1);animation:var(--strike-anim)}
.row.nofx .ink,.row.nofx .ghost{transition:none}
/* 1.12 b293: the strike in the material's hand (html[data-mat]): Ink a pen, Pixel square and stepped, Pencil a scribble (layoutStrikes) revealed by a clip */
html[data-mat="ink"] .ink{height:max(3px,.078em);border-radius:40% 60% 55% 45%/65% 45% 55% 35%;opacity:.93;rotate:.45deg}
html[data-mat="ink"] .ink:nth-child(4n){rotate:-.6deg}
html[data-mat="pixel"] .ink{height:max(4px,.11em);border-radius:0;transition-timing-function:steps(6,end)}
.ink.scr{height:.5em;margin-top:-.22em;background:none;box-shadow:none;transform:none;clip-path:inset(-60% 100% -60% 0);transition:clip-path var(--t,.3s) var(--e,cubic-bezier(.5,0,.3,1)) var(--d,0s)}
.row.done .ink.scr{clip-path:inset(-60% 0 -60% 0)}
.row:not(.done) .ink.scr{transition-delay:var(--dr,0s)}
.ink.scr svg{display:block;width:100%;height:100%;overflow:visible}
.ink.scr path{fill:none;stroke:var(--strike-bg);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke}
@keyframes shimmer{to{background-position:-300% 0}}
@keyframes candy{to{background-position:-40px 0}}

/* motion that lands with the sound */
@keyframes kick{0%{transform:scale(1)}38%{transform:scale(1.018)}100%{transform:scale(1)}}
@keyframes pop{0%{transform:scale(1)}45%{transform:scale(1.22)}100%{transform:scale(1)}}
.row.kick{animation:kick .3s cubic-bezier(.3,1.4,.5,1)}
.box.pop{animation:pop .34s cubic-bezier(.3,1.5,.5,1)}
@keyframes arrive{from{opacity:0;transform:translateY(.25em)}to{opacity:1;transform:none}}
.row.arrive{animation:arrive .45s cubic-bezier(.22,1,.36,1)}

/* row tools: pencil / star / handle */
.tools{
  flex:0 0 auto;display:flex;align-items:center;gap:.15em;
  margin-top:.12em;margin-left:auto;
  font-family:var(--font-ui);font-size:clamp(13px,.42em,20px);
}
.tool{
  width:2.4em;height:2.4em;min-width:32px;min-height:32px;
  display:grid;place-items:center;border-radius:999px;
  background:transparent;border:1px solid transparent;color:var(--dim);cursor:pointer;
  transition:color .16s ease,border-color .16s ease,opacity .16s ease,background-color .16s ease;
  line-height:1;
}
.tool svg{width:1.05em;height:1.05em;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.tool:hover{color:var(--text);border-color:var(--hair-hi);background:var(--ink-3)}
.tool:focus-visible{outline:2px solid var(--accent);outline-offset:2px;opacity:1}
/* the Today toggle (Everything): a small star, hollow when off, filled when on; no pill, and no orange until hover or press */
.tool.today{position:relative;color:var(--dim)}
.tool.today svg{width:1.15em;height:1.15em}
.tool.today[aria-pressed="true"]{color:var(--muted)}
.tool.today[aria-pressed="true"] svg{fill:currentColor}
.tool.today:hover,.tool.today:active,.tool.today[aria-pressed="true"]:hover{color:var(--accent-text);border-color:var(--hair-hi);background:var(--ink-3)}
/* hover tooltip on pointer devices only: the label already says what it does */
@media (hover:hover){
  .tool[data-tip]::after{
    content:attr(data-tip);position:absolute;left:50%;top:calc(100% + 6px);transform:translate(-50%,-4px);
    font-family:var(--font-ui);font-weight:400;font-size:12px;letter-spacing:.02em;text-transform:none;white-space:nowrap;
    color:var(--text);background:var(--ink-3);border:1px solid var(--hair-hi);border-radius:8px;padding:.35em .6em;
    opacity:0;pointer-events:none;transition:opacity .15s ease .35s,transform .15s ease .35s;z-index:6;
  }
  .tool[data-tip]:hover::after,.tool[data-tip]:focus-visible::after{opacity:1;pointer-events:auto;transform:translate(-50%,0)}
  body.no-tip .tool[data-tip]::after{opacity:0 !important;pointer-events:none !important}
}
.tool.lmenu{cursor:pointer}
/* quiet rows: nothing at rest on the desktop but the star; ⋯ (menu, and the drag handle) appears on hover */
@media (hover:hover){
  .row .tool{opacity:0}
  .row:hover .tool,.row:focus-within .tool,.row .tool.today{opacity:1}
}
@media (hover:none){
  .tool{min-width:44px;min-height:44px}
  .check{min-height:44px}
  /* no persistent per-row buttons on the phone: ⋯ stays for assistive tech only (a hold or a swipe right opens the menu) */
  .tool.lmenu{position:absolute;width:1px;height:1px;min-width:0;min-height:0;overflow:hidden;clip:rect(0 0 0 0);opacity:0} /* 1.7: no pointer-events:none — VoiceOver's double-tap is a touch at the element, and it must land here, not on the line */
}

/* inline edit */
.einput{
  flex:1 1 auto;min-width:0;display:block;width:100%;resize:none;overflow:hidden;
  font-family:var(--font-task);font-size:inherit;font-weight:var(--task-w);letter-spacing:var(--task-ls);line-height:var(--task-lh);
  color:var(--text);background:var(--ink-2);
  border:1px solid var(--hair);border-bottom-color:var(--accent);border-radius:.14em;
  padding:.02em .2em;margin:-.03em 0 0 -.2em;
}
.row.editing .check{flex-wrap:wrap;cursor:default}
.einput.note-in{flex:1 1 100%;margin-left:calc(.66em + .46em);width:auto}
.einput::placeholder{color:var(--dim);opacity:1}
.einput:focus{outline:2px solid var(--accent);outline-offset:2px;border-color:var(--accent);background:var(--ink-3)}
.row.editing .lines,.row.editing .cap{display:none}
.row.editing .box{opacity:.5}

/* ---------------- everything ---------------- */
#all{overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--ink-3) transparent;padding-right:.2rem}
#all .row{font-size:clamp(1.1rem,1.9vh + .5vw,1.9rem);padding:.28em .3em .28em .2em}
#all .row .box{margin-top:.2em}
#all .row .tools{font-size:clamp(13px,.55em,18px)}
#all .note{display:block}
.sec{margin-bottom:clamp(.6rem,1.8vh,1.4rem)}
.sec-h{
  display:flex;align-items:center;gap:.6rem;
  font-family:var(--font-ui);font-weight:700;font-size:clamp(9.5px,1.05vw,12px);
  letter-spacing:.15em;text-transform:uppercase;color:var(--dim);
  padding:.3rem 0 .35rem;border-bottom:1px solid var(--hair);margin-bottom:.25rem;
  min-height:36px;
}
.sec-h .sec-toggle{
  display:inline-flex;align-items:center;gap:.5em;background:transparent;border:0;color:inherit;
  font:inherit;letter-spacing:inherit;text-transform:inherit;cursor:pointer;padding:.3em .2em;min-height:32px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:60%;
}
.sec-h .sec-toggle:hover{color:var(--text)}
.sec-h .sec-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.sec-h .caret{display:inline-block;transition:transform .2s ease;font-size:.9em}
.sec.collapsed .caret{transform:rotate(-90deg)}
.sec-h .sec-count{color:var(--muted);letter-spacing:.09em;font-variant-numeric:tabular-nums}
.sec-h .spacer{flex:1 1 auto}
.sec-h .chip{padding:.35em .7em;min-height:32px} /* 1.7: the chip floor, like the rail's ⋯ */
.sec.collapsed .seclist,.sec.collapsed .add{display:none}
.sec.over .sec-h{color:var(--accent-text);border-bottom-color:var(--accent)}
.seclist{list-style:none;display:flex;flex-direction:column;min-height:.5rem}
.add{
  align-self:flex-start;margin:.35rem 0 0 .2rem;
  font-family:var(--font-ui);font-weight:700;font-size:clamp(10px,1.05vw,12px);
  letter-spacing:.15em;text-transform:uppercase;color:var(--dim);
  background:transparent;border:1px dashed var(--hair);border-radius:999px;
  padding:.55em 1.1em;cursor:pointer;min-height:32px;
  transition:color .16s ease,border-color .16s ease;
}
.add:hover{color:var(--accent-text);border-color:var(--accent)}
.add:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
#addsec{margin-top:.2rem}
#today-empty{margin:.2rem 0 .6rem;padding:.35em .6em .35em .1em}
.empty{
  font-family:var(--font-ui);font-size:clamp(11px,1.2vw,14px);letter-spacing:.06em;color:var(--dim);
  padding:.6rem .3rem;
}

/* drag */
.row.dragging{
  z-index:5;background:var(--ink-3);box-shadow:0 12px 32px rgba(0,0,0,.35);--done:var(--done-2); /* 1.9: a done line reads at 4.5:1 while lifted (proposal 29) */
  transition:none;cursor:grabbing;
}
.row.dragging .tool{opacity:1}
body.is-dragging{cursor:grabbing}
body.is-dragging .row:hover{background:transparent}
/* 1.9: a row on its way to a new place (a done line sinking, a remote reorder) carries the page's own ground and sits above the rows it
   passes, so the reorder reads as one object moving past another instead of two lines of type drawn over each other; the crossed-off
   line rides on top of the rows it displaces. app.js adds the class for the length of the FLIP. */
.row.moving{background:var(--ink);z-index:2;transition-property:color} /* the ground is there from the first frame: the row's .2s background fade would let the rows show through while they cross */
.row.moving.done{z-index:3}
.no-hover .row.moving:hover{background:var(--ink)}

/* ---------------- view-only mode: nothing that edits is rendered ---------------- */
/* 1.12 b387: a line's tools, not the rail's (the sun/moon, Share and ⋯ are `.tools` too since 1.9, and a viewer needs ⋯) */
html[data-mode="view"] .row .tools,html[data-mode="view"] .add,html[data-mode="view"] #addtoday,html[data-mode="view"] .sec-more,
html[data-mode="view"] #again,html[data-mode="view"] #c-save,html[data-mode="view"] .swatch .del,html[data-mode="view"] #l-rename,
html[data-mode="view"] #toast-undo{display:none !important}
html[data-mode="view"] .check{cursor:default}
html[data-mode="view"] .row:hover{background:transparent}
html[data-mode="view"] .row:hover .box{border-color:var(--hair-solid)}
html[data-mode="view"] .row:hover:not(.done) .ghost{opacity:0}
html[data-mode="view"] #hint{visibility:hidden}

/* ---------------- footer ---------------- */
#foot{flex:0 0 auto;position:relative;display:flex;flex-direction:column;align-items:center;font-family:var(--font-ui)}
.foot-row{position:relative;min-height:clamp(3.1rem,7.4vh,4.6rem);display:grid;place-items:center;width:100%}
.foot-row>*{grid-area:1/1;transition:opacity .5s ease}
#hint{
  font-family:var(--font-ui);font-weight:700;font-size:clamp(9px,1vw,11.5px);
  letter-spacing:.16em;text-transform:uppercase;color:var(--dim);
  text-align:center;line-height:2;
}
#hint em{font-style:normal;color:var(--muted)}
#hint.off{opacity:0;pointer-events:none}
/* the finale is not laid out until it is on: an invisible row in the row font pulled Lato 900 (and, through its chip, Lato 400) in at first paint */
#finale{display:none;align-items:center;gap:1.1rem;flex-wrap:wrap;justify-content:center}
#finale .chip{font-family:var(--font-ui);font-weight:700;font-size:clamp(10px,1.05vw,12px);letter-spacing:.15em;text-transform:uppercase} /* 1.7: the rail's chip style, not body text */
#finale.on{display:flex;animation:finale-in .5s ease}
@keyframes finale-in{from{opacity:0}to{opacity:1}}
/* 1.12 b401: the day stamps itself sealed, where no scene is playing (a scene's own moment is its finish there). A rubber
   stamp in the kit's own ink, pressed a little askew, its ink a little worn: a still speckle mask, nothing that moves at
   rest. The words are the material's (app.js stampWords). A seal's double frame: the border, and a hairline inside it.
   Its room on the card is kept from the first frame (.wait), so the card never re-wraps when it comes down. A digital
   material's stamp is crisp: no wear, square corners (Pixel's inner frame dashed, like a sprite's). */
#finale .stamp{display:inline-block;font:700 clamp(10px,1.05vw,12px)/1 var(--font-ui);letter-spacing:.2em;text-transform:uppercase;white-space:nowrap;color:var(--accent-text);border:2px solid currentColor;border-radius:5px;outline:1px solid currentColor;outline-offset:-5px;padding:.86em 1.1em .82em;transform:rotate(-4deg);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='32'%3E%3Cfilter id='w' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.75' numOctaves='2' seed='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 -3.2 0 0 0 2.75'/%3E%3C/filter%3E%3Crect width='96' height='32' filter='url(%23w)'/%3E%3C/svg%3E") 0 0/96px 32px;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='32'%3E%3Cfilter id='w' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.75' numOctaves='2' seed='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 -3.2 0 0 0 2.75'/%3E%3C/filter%3E%3Crect width='96' height='32' filter='url(%23w)'/%3E%3C/svg%3E") 0 0/96px 32px}
#finale .stamp.wait{visibility:hidden}
html[data-mat="phosphor"] #finale .stamp,html[data-mat="pixel"] #finale .stamp{border-radius:0;-webkit-mask:none;mask:none}
html[data-mat="pixel"] #finale .stamp{outline-style:dashed} /* a pixel frame */
#finale span{
  font-family:var(--font-task);font-weight:var(--task-w);letter-spacing:var(--task-ls);
  font-size:clamp(1.1rem,2.7vh,1.9rem);color:var(--accent-text);font-style:var(--finale-style);
}
#toast{
  position:fixed;left:50%;bottom:calc(58px + env(safe-area-inset-bottom,0px));z-index:50;
  display:flex;align-items:center;gap:.8rem;
  font-family:var(--font-ui);font-weight:700;font-size:clamp(10px,1.05vw,12.5px);
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted);
  background:var(--ink-2);border:1px solid var(--hair);border-radius:999px;
  padding:.5em 1em .5em 1.2em;opacity:0;pointer-events:none;transform:translate(-50%,6px);
  transition:opacity .25s ease,transform .25s ease;max-width:min(92vw,40rem);
}
#toast.on{opacity:1;pointer-events:auto;transform:translate(-50%,0)}
dialog.panel #toast{z-index:60} /* 1.7: a toast raised while a sheet is open moves inside the sheet, above its backdrop, readable and pressable; it moves back out when it hides */
#toast .msg{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#toast .chip{color:var(--accent-text);border-color:var(--accent);min-height:36px}
#toast .key{color:var(--muted);letter-spacing:.09em;margin-left:.55em} /* 1.9: the shortcut beside Undo, for the keyboard user it sits past every row from (proposal 28) */

/* ---------------- progress ---------------- */
/* the track is transparent (an empty 3 px of --ink-3 read as a hairline under the iPhone's home indicator);
   only the fill draws, and it sits above the safe-area inset */
#bar{position:fixed;left:0;right:0;bottom:env(safe-area-inset-bottom,0px);height:3px;background:transparent;z-index:40;pointer-events:none}
#fill{height:100%;width:0%;background:var(--bar-bg,linear-gradient(90deg,var(--accent-deep),var(--accent) 55%,var(--accent-hi)));transition:width .5s cubic-bezier(.22,1,.36,1),box-shadow .4s ease} /* the fallback is the token's own default (theme.js), for the first frame */
#fill.full{box-shadow:0 0 24px 2px var(--accent)}
/* 1.12: Today and Everything each have their own numbers, so switching views is not progress — the bar lands at the
   new width instead of sliding to it (app.js drops the class on the frame after the swap) */
#fill.nofade{transition:none}

/* ---------------- welcome ---------------- */
#welcome{align-items:center;justify-content:center;text-align:center;gap:1.2rem;padding:1rem 0}
#welcome h1{font-family:var(--font-task);font-weight:var(--task-w);letter-spacing:var(--task-ls);font-size:clamp(2rem,7vh,4.2rem);line-height:1.05}
#welcome p,#demo-foot p{font-family:var(--font-ui);color:var(--muted);font-size:clamp(13px,1.3vw,16px);max-width:34rem;line-height:1.5} /* the foot too: in the row font its About link pulled Lato 400 in at first paint */
#welcome .actions,#demo-foot .actions{display:flex;flex-wrap:wrap;gap:.8rem;justify-content:center}
#welcome .big,#demo-foot .big{
  font-family:var(--font-ui);font-weight:700;font-size:clamp(12px,1.2vw,14px);letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent-text);background:transparent;border:1px solid var(--accent);border-radius:999px;
  padding:.9em 1.6em;cursor:pointer;min-height:44px;
}
#welcome .big:hover,#demo-foot .big:hover{background:var(--ink-2)}
#welcome .big.quiet,#demo-foot .big.quiet{color:var(--muted);border-color:var(--hair-hi)}
#welcome .big.quiet:hover,#demo-foot .big.quiet:hover{color:var(--text)}
#welcome .fine,#demo-foot .fine{margin-top:.2rem}
#welcome .big:focus-visible,#demo-foot .big:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
#welcome .paste,#demo-foot .paste{display:flex;gap:.5rem;justify-content:center;width:100%;max-width:34rem}
#welcome .paste input,#demo-foot .paste input{
  flex:1 1 auto;min-width:0;font-family:var(--font-ui);font-size:15px;color:var(--text);
  background:var(--ink-2);border:1px solid var(--hair);border-radius:999px;padding:.7em 1.1em;min-height:44px;
}
#welcome .paste input:focus,#demo-foot .paste input:focus{outline:2px solid var(--accent);outline-offset:2px;border-color:var(--accent)}
#welcome .err,#demo-foot .err{color:var(--danger);min-height:1.4em;font-size:13px}

/* text on the elevated surfaces (--ink-2 / --ink-3) uses the greys guaranteed to clear 4.5:1 there (panels.css does the same for dialogs) */
#toast,#install,.row.editing .einput{--dim:var(--dim-2);--muted:var(--muted-2)}

/* ---------------- install hint ---------------- */
#install{
  position:fixed;left:50%;bottom:calc(14px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);z-index:45;
  display:flex;align-items:center;gap:.8rem;max-width:92vw;
  font-family:var(--font-ui);font-size:13px;color:var(--text);
  background:var(--ink-2);border:1px solid var(--hair-hi);border-radius:14px;padding:.7rem .9rem .7rem 1rem;
  box-shadow:0 12px 40px rgba(0,0,0,.4);
}
#install .x{width:36px;height:36px;border-radius:999px;border:0;background:transparent;color:var(--dim);font-size:18px;cursor:pointer}

/* ---------------- responsive ---------------- */
@media (max-width:900px){ #date{display:none} }
/* 1.9: the rail wraps before it truncates. It is measured by its own width, not the viewport's — the page margins grow with the
   text, so at 200 % text on a 390 px phone the rail is 332 px wide — and under 341 px a list chip takes the first line whole, the
   count and the tools the next, and the tabs drop below them, whole. At 341 px and up nothing moves; a browser without container
   queries keeps 1.8's rail (proposal 27) */
.rail-wrap{flex:0 0 auto;container-type:inline-size}
@container (max-width:340px){
  .rail{flex-wrap:wrap;row-gap:.4rem}
  .rail-l{display:contents} /* the chip and the pills join the rail's own line-breaking; an empty group leaves no empty line */
  .rail-r{flex:1 1 auto;flex-wrap:wrap;justify-content:space-between;gap:.3rem;row-gap:.4rem}
  .rail-r .tools{margin-left:auto}
  .rail-r .tools,.rail-r .status{gap:.3rem} /* the count, the tabs and the tools share one line at 200 % text on a 390 px phone */
}
@media (max-width:680px){
  .rail{letter-spacing:.1em;gap:.5rem}
  #share{display:none}
  .chip,.seg button{min-height:44px}
  .chip.icon{min-width:44px}
  .seg button{padding:.45em .7em}
  #list .cap{display:none}
  #shell{padding-left:calc(.9rem + env(safe-area-inset-left,0px));padding-right:calc(.9rem + env(safe-area-inset-right,0px))}
  #hint{display:none}
  dialog.panel{width:min(94vw,30rem)}
}

/* on touch, tappable things look tappable: filled chips, stronger hairlines, no hover-only states */
@media (hover:none){
  .chip,.seg,.add,.dot,.tool{--dim:var(--dim-2);--muted:var(--muted-2)}
  .chip,.seg,.add{background:var(--ink-2);border-color:var(--hair-hi)}
  .chip.plain{background:transparent;border-color:transparent}
  .seg button[aria-selected="true"]{background:var(--ink-3)}
  .tool.today{border-color:transparent;background:transparent}
  .dot{min-height:44px;min-width:32px;justify-content:center}
  .sec-h .chip{min-width:44px}
  #count,#shuffle{min-height:44px;min-width:44px} /* 1.7: the count is a control, at the touch floor like the chips */
  #count,#shuffle{background:var(--ink-2);border:1px solid var(--hair-hi);padding:.45em .8em} /* 1.9: on a phone the count looks like the tappable thing it is (proposal 11) */
  .row .tool{opacity:1}
}

/* 1.12 b293: the unseal — a list opened here arrives in its material while the lock over the dot opens (app.js unseal, --i per row) */
html.unseal #main .row{animation:var(--us,tf-us-rise) var(--us-d,.5s) var(--us-e,cubic-bezier(.22,1,.36,1)) calc(80ms + var(--i,0) * var(--us-s,70ms)) backwards}
html[data-mat="ink"]{--us:tf-us-develop;--us-d:.78s;--us-s:120ms;--us-e:cubic-bezier(.3,.1,.2,1)}
html[data-mat="glass"]{--us:tf-us-focus;--us-d:.64s;--us-s:90ms}
html.unseal[data-mat="glass"] #main .row{transform-origin:0 50%}
html[data-mat="tide"]{--us:tf-us-mist;--us-d:.95s;--us-s:150ms;--us-e:cubic-bezier(.2,.7,.2,1)}
html[data-mat="candy"]{--us:tf-us-pop;--us-d:.52s;--us-s:110ms;--us-e:cubic-bezier(.3,1.5,.5,1)}
html[data-mat="phosphor"]{--us:tf-us-type;--us-d:.46s;--us-s:110ms;--us-e:steps(16,end)}
html[data-mat="pixel"]{--us:tf-us-type;--us-d:.5s;--us-s:120ms;--us-e:steps(7,end)}
html[data-mat="glow"]{--us:tf-us-dawn;--us-d:1.05s;--us-s:130ms;--us-e:cubic-bezier(.3,.1,.2,1)}
html[data-mat="ember"]{--us:tf-us-kindle;--us-d:1.15s;--us-s:120ms;--us-e:ease-out}
html[data-mat="pencil"],html[data-mat="chalk"]{--us:tf-us-sketch;--us-d:.62s;--us-s:170ms;--us-e:cubic-bezier(.5,0,.3,1)}
@keyframes tf-us-rise{from{opacity:0;transform:translateY(16px)}}
@keyframes tf-us-develop{from{opacity:.1;filter:blur(10px) sepia(1)}45%{opacity:.7;filter:blur(3px) sepia(.6)}}
@keyframes tf-us-focus{from{opacity:.15;filter:blur(12px) brightness(1.7);transform:scale(1.05)}}
@keyframes tf-us-mist{from{opacity:0;filter:blur(6px);transform:translateY(26px)}}
@keyframes tf-us-pop{from{opacity:0;transform:scale(.6)}}
@keyframes tf-us-type{from{clip-path:inset(-20% 100% -20% 0)}to{clip-path:inset(-20% 0 -20% 0)}}
@keyframes tf-us-dawn{from{opacity:0;filter:blur(5px) brightness(2)}50%{opacity:.85;filter:blur(1px) brightness(1.4)}}
@keyframes tf-us-kindle{from{opacity:.2;color:var(--accent-hi);text-shadow:0 0 22px rgba(255,120,40,.95)}40%{opacity:1;color:var(--accent-hi);text-shadow:0 0 14px rgba(255,120,40,.7)}}
@keyframes tf-us-sketch{from{clip-path:inset(-20% 100% -20% 0);filter:blur(1.5px)}to{clip-path:inset(-20% 0 -20% 0);filter:blur(0)}}
html.unseal .dot .lock{animation:tf-lock 1.5s both}
html.unseal .dot .lock .shackle{animation:tf-shackle 1.5s cubic-bezier(.3,1.4,.5,1) both}
html.unseal .dot::before{animation:tf-dot 1.5s both}
@keyframes tf-lock{8%,86%{opacity:1}}
@keyframes tf-shackle{30%{transform:none}48%,to{transform:translate(2px,-1.5px) rotate(32deg)}}
@keyframes tf-dot{8%,86%{opacity:0}}

@media (prefers-reduced-motion:reduce){
  html.unseal #main .row,html.unseal .dot .lock,html.unseal .dot .lock .shackle,html.unseal .dot::before{animation:none}
  .ink,.ghost{transition-duration:.08s}
  .row{transition:background-color .08s ease,color .08s ease}
  .box,.box path{transition-duration:.08s}
  #fill{transition-duration:.1s}
  #glow,#glow.flare{transition:none}
  .row.kick,.box.pop,.row.arrive{animation:none}
  .ink,.row.done .ink{animation:none}
  .dot[data-s="syncing"]::before{animation:none;opacity:.5}
  #finale.on{animation:none}
  .row.moving{transition:none}
  #toast{transition:none}
}

@media (hover:none){
  button.add,.sec-h button.chip,.sec-h button.sec-toggle{min-height:44px}
  .sec-h button.chip{min-width:44px}
  #install .x{width:44px;height:44px}
  input[type="range"]{min-height:44px}
  /* iOS zooms the page when a focused field is under 16px */
  input,select,textarea{font-size:max(16px,1em)}
  .einput.note-in{font-size:16px}
}

/* ---------------- about page ---------------- */
body.page{overflow:auto;height:auto;min-height:100%}
.prose{
  position:relative;z-index:2;max-width:40rem;margin:0 auto;
  padding:calc(2rem + env(safe-area-inset-top,0px)) calc(1.2rem + env(safe-area-inset-right,0px)) calc(3rem + env(safe-area-inset-bottom,0px)) calc(1.2rem + env(safe-area-inset-left,0px));
  font-family:var(--font-ui);font-size:16px;line-height:1.55;color:var(--text);
}
.prose h1{font-family:var(--font-task);font-weight:var(--task-w);letter-spacing:var(--task-ls);font-size:clamp(2rem,6vw,3.2rem);line-height:1.05;margin:.4rem 0 .8rem}
.prose h2{font-family:var(--font-ui);font-weight:700;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--dim);margin:1.8rem 0 .5rem;padding-top:1rem;border-top:1px solid var(--hair)}
.prose p,.prose li{color:var(--text);margin:.5rem 0}
.prose .lede{font-size:18px;color:var(--muted)}
.prose ul{padding-left:1.2rem}
.prose li{margin:.35rem 0}
.prose b,.prose strong{color:var(--text)}
.prose code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.9em;background:var(--ink-2);border:1px solid var(--hair);border-radius:6px;padding:.05em .35em}
.prose a{color:var(--accent-text)}
.prose .crumb{font-size:12px;letter-spacing:.12em;text-transform:uppercase;font-weight:700}
.prose .crumb a{color:var(--accent-text);text-decoration:none}
.prose .crumb .chev{font-size:1.7em;line-height:.8;font-weight:400;position:relative;top:-.06em;margin-right:.15em} /* 1.7: the same way back as every panel's */
.prose .crumb a:hover{color:var(--text)}
.prose .fine{margin-top:2rem}
/* the version line and the changelog (1.2): a headline per version, then up to three tagged items (About loads this sheet only) */
.prose .version{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim);margin:.2rem 0 1rem}
.prose .log{list-style:none;padding:0}
.prose .log>li{margin:1rem 0}
.prose .log .v{font-weight:700;color:var(--text)}
.prose .log .hl{color:var(--text)}
.prose .log ul{list-style:none;margin:.35rem 0 0;padding:0}
.prose .log ul li{display:flex;gap:.6rem;align-items:baseline;margin:.3rem 0}
.prose .log .tag{flex:0 0 5.2em;font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--accent-text);border:1px solid var(--hair-hi);border-radius:999px;padding:.15em .6em;text-align:center}
.prose .log .tag.fixed{color:var(--muted)}


/* ================= v4 ================= */

/* who's here: one dot per other device beside the sync dot, five at most then "+n" */
.who{display:inline-flex;align-items:center;gap:3px;min-height:32px}
.who .dots{display:inline-flex;gap:3px}
.who .dots i{width:7px;height:7px;border-radius:50%;background:var(--muted);opacity:0;transform:scale(.4);transition:opacity .4s ease,transform .4s cubic-bezier(.22,1,.36,1)}
.who .dots i.on{opacity:.9;transform:none}
.who .plus{font-size:.85em;color:var(--dim);letter-spacing:.04em}
.who.fade{opacity:0;transition:opacity .4s ease}

/* the line menu, the repeat glyph, the tomorrow marker */
.tool.lmenu{font-size:1.1em;letter-spacing:0;line-height:1}
.rep{display:inline-block;margin-left:.35em;font-size:.55em;color:var(--dim);vertical-align:middle;transform:translateY(-.1em);font-family:var(--font-ui)}
.row.done .rep{color:var(--done)}
.cap.tmr{color:var(--accent-text);border:1px solid var(--accent);border-radius:999px;padding:.1em .5em;font-size:clamp(9px,.26em,12px)}
#list .cap.tmr{display:none}
.row.swiping{transition:none}
.row.swipe-out{transition:transform .25s ease,opacity .25s ease;opacity:0}

/* the editor's repeat chip */
.erow{flex:1 1 100%;margin-left:calc(.66em + .46em);display:flex;gap:.4rem;align-items:center;margin-top:.2em}
.erow .chip{font-family:var(--font-ui);font-weight:700;font-size:clamp(10px,.3em,12px);letter-spacing:.12em;text-transform:uppercase;min-height:32px}
.erow .chip.on{color:var(--accent-text);border-color:var(--accent)}
.cap-count{margin-left:auto;font-family:var(--font-ui);font-weight:700;font-size:clamp(10px,.3em,12px);letter-spacing:.08em;color:var(--dim);font-variant-numeric:tabular-nums} /* 1.9: the last twenty characters before a cap */

/* everything's header: search */
.all-head{display:flex;align-items:center;gap:.5rem;margin-bottom:.35rem;min-height:36px;font-family:var(--font-ui);font-weight:700;font-size:clamp(9.5px,1.05vw,12px);letter-spacing:.15em;text-transform:uppercase}
.all-head .chip[aria-expanded="true"]{color:var(--accent-text);border-color:var(--accent)}
.all-head .chip .key{color:var(--muted);letter-spacing:.09em}
#search{
  flex:1 1 auto;min-width:0;max-width:26rem;font-family:var(--font-ui);font-size:15px;color:var(--text);
  background:var(--ink-2);border:1px solid var(--hair);border-radius:999px;padding:.45em 1em;min-height:36px;
}
#search:focus{outline:2px solid var(--accent);outline-offset:2px;border-color:var(--accent)}
#all.searching .row.miss{display:none}
#all.searching .sec.nohit{display:none}
#all.searching .sec .add,#all.searching #addsec,#all.searching .empty{display:none}
.nohits{font-family:var(--font-ui);font-size:14px;color:var(--dim);padding:.8rem .3rem}

/* recently deleted: a shelf at the bottom of Everything */
.deleted{margin-top:clamp(.8rem,2.4vh,1.6rem);border-top:1px solid var(--hair);padding-top:.5rem}
.deleted summary{
  list-style:none;cursor:pointer;display:flex;align-items:center;gap:.5rem;min-height:36px;
  font-family:var(--font-ui);font-weight:700;font-size:clamp(9.5px,1.05vw,12px);letter-spacing:.15em;text-transform:uppercase;color:var(--dim);
}
.deleted summary::-webkit-details-marker{display:none}
.deleted summary .caret{display:inline-block;transition:transform .2s ease}
.deleted[open] summary .caret{transform:rotate(90deg)}
.deleted summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.deleted ul{list-style:none;display:flex;flex-direction:column;gap:2px;margin:.3rem 0 0}
.deleted li{display:flex;align-items:center;gap:.8rem;padding:.35em .3em;font-family:var(--font-ui);font-size:clamp(13px,1.6vh,16px);color:var(--muted);min-height:40px}
.deleted li .t{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-decoration:line-through;text-decoration-color:var(--hair-hi)}
.deleted li .chip{font-family:var(--font-ui);font-weight:700;font-size:10px;letter-spacing:.12em;text-transform:uppercase;min-height:32px;flex:0 0 auto}

/* one-thing mode: the top undone line, enormous; the rest wait their turn */
body.one #list{justify-content:center}
body.one #list .row:not(.one-now){display:none}
body.one #list .row.one-now{font-size:clamp(2.2rem,min(13vw,18vh),8rem);padding:.3em .3em}
body.one #list .row.one-now .tools{display:none}
body.one #addtoday{display:none}
body.one #list .row.one-now .cap{display:none}
@keyframes one-in{from{opacity:0;transform:translateY(.35em)}to{opacity:1;transform:none}}
body.one #list .row.one-now.arrive{animation:one-in .45s cubic-bezier(.22,1,.36,1)}
.one-more{display:none;font-family:var(--font-ui);font-weight:700;font-size:clamp(10px,1.05vw,12px);letter-spacing:.15em;text-transform:uppercase;color:var(--dim);text-align:center;margin-top:.6rem}
body.one .one-more{display:block}

/* day review: a quiet card under the finale */
.review{
  width:min(100%,34rem);margin:.2rem auto .4rem;padding:.8rem 1rem;border:1px solid var(--hair);border-radius:14px;background:var(--ink-2);
  font-family:var(--font-ui);font-size:14px;color:var(--muted);display:flex;flex-direction:column;gap:.5rem;
  --dim:var(--dim-2);--muted:var(--muted-2);
}
.review .r-head{display:flex;align-items:center;justify-content:space-between;gap:1rem;font-weight:700;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.review .r-streak{color:var(--accent-text)}
.review .r-week{display:flex;gap:.35rem;align-items:center}
.review .r-week i{width:.9rem;height:.9rem;border-radius:50%;border:1px solid var(--hair-hi);display:inline-block}
.review .r-week i.on{background:var(--accent);border-color:var(--accent)}
.review .r-week i.future{opacity:.35}
.review .r-week span{margin-left:.4rem;font-size:12px}
.review ul{list-style:none;display:flex;flex-wrap:wrap;gap:.25rem .9rem;margin:0;padding:0}
.review li{font-size:13px;color:var(--text)}
.review li.done{color:var(--dim);text-decoration:line-through;text-decoration-color:var(--hair-hi)}

/* what's new: a small toast after an update, never on first run */
#whatsnew{
  position:fixed;left:50%;bottom:calc(58px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);z-index:49;
  display:flex;align-items:center;gap:.6rem;width:min(92vw,36rem);box-sizing:border-box;
  font-family:var(--font-ui);font-size:13px;color:var(--text);
  background:var(--ink-2);border:1px solid var(--hair-hi);border-radius:14px;padding:.55rem .5rem .55rem .9rem;
  box-shadow:0 12px 40px rgba(0,0,0,.35);--dim:var(--dim-2);--muted:var(--muted-2);
}
#whatsnew .msg{flex:1 1 auto;min-width:0}
#whatsnew .chip{font-family:var(--font-ui);font-weight:700;font-size:10px;letter-spacing:.12em;text-transform:uppercase;min-height:36px;color:var(--accent-text);border-color:var(--accent);flex:0 0 auto}
#whatsnew .x{width:36px;height:36px;border-radius:999px;border:0;background:transparent;color:var(--dim);font-size:18px;cursor:pointer;flex:0 0 auto}
body.one #whatsnew,body.one #toast{bottom:calc(24px + env(safe-area-inset-bottom,0px))}
body.install-on #toast,body.install-on #whatsnew{bottom:calc(96px + env(safe-area-inset-bottom,0px))}
body.fin-tall #toast{bottom:calc(58px + var(--fin-extra,0px) + env(safe-area-inset-bottom,0px))} /* 1.12 b293: above a finale card that wrapped */

/* the iOS haptic switch: off screen, never focusable, never painted where it can be seen */
.haptic{position:fixed;left:-200px;top:-200px;width:1px;height:1px;opacity:0;pointer-events:none}

@media (hover:none){
  .sw{width:46px;height:28px}
  .sw::after{width:20px;height:20px}
  .row-toggle[aria-pressed="true"] .sw::after{transform:translateX(18px)}
  .all-head .chip{min-height:44px}
  .all-head .chip .key{display:none}
  #toast .key{display:none} /* 1.9: no key to press on a phone */
  #search{min-height:44px;font-size:16px}
  .deleted li .chip{min-height:40px}
}
@media (prefers-reduced-motion:reduce){
  .who .dots i,.sw,.sw::after{transition:none}
  body.one #list .row.one-now.arrive{animation:none}
  .row.swipe-out{transition:none}
}

/* ================= 1.1 ================= */

/* just-in-time hints: one line beside the real control, once per device; the control gets a ring meanwhile */
#mark{
  position:fixed;z-index:65;max-width:min(24rem,calc(100vw - 2rem));pointer-events:none;
  font-family:var(--font-ui);font-size:14px;line-height:1.4;color:var(--text);
  background:var(--ink-2);border:1px solid var(--hair-hi);border-radius:12px;padding:.55rem .85rem;
  box-shadow:0 12px 40px rgba(0,0,0,.35);--dim:var(--dim-2);--muted:var(--muted-2);
  animation:mark-in .22s cubic-bezier(.22,1,.36,1);
}
#mark::before{content:"";position:absolute;width:12px;height:12px;background:var(--ink-2);border:1px solid var(--hair-hi);transform:rotate(45deg);left:var(--arrow-x,50%);margin-left:-6px}
#mark[data-place="below"]::before{top:-7px;border-right:0;border-bottom:0}
#mark[data-place="above"]::before{bottom:-7px;border-left:0;border-top:0}
@keyframes mark-in{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.marked{outline:2px solid var(--accent) !important;outline-offset:3px}
.row.marked-row .tool{opacity:1}
@media (prefers-reduced-motion:reduce){#mark{animation:none}}

/* the rail (1.1): date · count with the sync dot beside it (and the presence dots) · Today/Everything · Share · ⋯ */
.rail-r .status{display:inline-flex;align-items:center;gap:.4rem;min-width:0}
/* the sun/moon (1.2): between the views and Share, showing where a tap goes (the moon by day, the sun by night); it fades with the rail */
#daynight{display:inline-grid;place-items:center;padding:.45em .6em}
#daynight svg{width:15px;height:15px;display:block;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
#daynight[data-next="night"] .sun,#daynight[data-next="day"] .moon{display:none}
/* while the palette crossfades, the tokens move every frame: the rows' and chips' own colour transitions would trail them
   (pale text on a pale ground for a beat), so they are off until the fade lands; the glow keeps its inline dip */
body.fading *:not(#glow),body.fading .dot::before{transition-property:none !important}
/* welcome: no rail, no footer */
body.welcome .rail,body.welcome #foot,html.welcome .rail,html.welcome #foot{display:none} /* html.welcome: the boot script's guess, before first paint */
html.welcome #today{display:none} /* and the empty list stays out of the first paint too: the welcome slots in above it and would push it down */
/* idle fade (desktop): the rail and the footer step back to the date and the count; the presence dots stay */
.rail-r > *,.rail-l > *,#foot{transition:opacity .25s ease}
body.idle .rail-r > :not(.status),body.idle .rail-l > :not(#date),body.idle #foot{opacity:.2;transition:opacity 1.4s ease} /* 1.9: to 0.2, not 0 — the quiet survives and a slow-reading mouse user can still see what is there to click (proposal 26) */

/* ================= 1.3 ================= */

/* the welcome is a live list (1.3): the title and one sentence above #today, Keep / Skip / Paste below it */
body.welcome #welcome{order:-1;gap:.5rem;padding:.2rem 0 .3rem;flex:0 0 auto}
body.welcome #welcome h1{font-size:clamp(1.7rem,5.5vh,3.4rem)}
body.welcome #today{flex:0 1 auto;min-height:0}
body.welcome #list{max-height:56vh}
#demo-foot{order:1;flex:0 0 auto;align-items:center;justify-content:flex-start;text-align:center;gap:.6rem;padding:.4rem 0 0}
#demo-foot .actions{min-height:0}
.quiet-links{font-family:var(--font-ui);font-size:clamp(12px,1.2vw,14px);color:var(--muted);display:flex;flex-wrap:wrap;justify-content:center;gap:.2rem .5rem;align-items:center}
.quiet-links .sep{color:var(--dim)}
.linkish{font:inherit;color:var(--muted);background:transparent;border:0;padding:.35em .2em;cursor:pointer;text-decoration:underline;text-decoration-color:var(--hair-hi);text-underline-offset:.2em;min-height:32px}
.linkish:hover{color:var(--text)}
.linkish:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
@keyframes keep-in{from{opacity:0;transform:translateY(.3rem)}to{opacity:1;transform:none}}
#w-keep{animation:keep-in .35s cubic-bezier(.22,1,.36,1)}
body.welcome #demo-foot .paste{max-width:30rem}

/* the view-only pill names the link on the desktop; the phone's rail has room for the state alone */
@media (max-width:680px){ .ro-l{display:none} }
/* 1.12 b389: a View link's rail wraps before it clips. It carries the View only pill (and Shared, for someone else's list)
   besides all an owner's rail has, so where the line runs out the count, the tabs and the tools take a line of their own,
   on the right where they always sit, and the list's chip and the pills keep the first; where it all fits nothing moves */
html[data-mode="view"] .rail{flex-wrap:wrap;row-gap:.4rem}
html[data-mode="view"] .rail-r{margin-left:auto}
/* 1.12 b393: so does the rail of someone else's list one can edit, which carries the Shared pill and the list's chip
   besides the tools (on a phone its tabs were clipped). Rules of their own: a browser without :has() keeps the rail as
   it was, and the View link's rules above never depend on it */
.rail:has(#shared:not([hidden])){flex-wrap:wrap;row-gap:.4rem}
.rail:has(#shared:not([hidden])) .rail-r{margin-left:auto}

/* shuffle (1.3): ↻ beside the count, only inside one-thing mode; the shown line slides out and the next slides in */
#shuffle{display:none;color:var(--muted);letter-spacing:0;font-size:1.15em;padding:.2em .35em;min-width:32px;line-height:1}
#shuffle:hover{color:var(--accent-text)}
body.one #shuffle{display:inline-flex;align-items:center;justify-content:center}
@keyframes one-out{to{opacity:0;transform:translateX(-.3em)}}
@keyframes one-shuffle-in{from{opacity:0;transform:translateX(.3em)}to{opacity:1;transform:none}}
@keyframes wobble{0%,100%{transform:none}25%{transform:translateX(-.06em)}75%{transform:translateX(.06em)}}
body.one #list .row.one-now.shuffle-out{animation:one-out .16s ease forwards}
body.one #list .row.one-now.shuffle-in{animation:one-shuffle-in .28s cubic-bezier(.22,1,.36,1)}
body.one #list .row.one-now.wobble{animation:wobble .36s ease}
@media (prefers-reduced-motion:reduce){ body.one #list .row.one-now.shuffle-out,body.one #list .row.one-now.shuffle-in,body.one #list .row.one-now.wobble,#w-keep{animation:none} }

/* the shake permission hint (one-thing mode on a phone, once): the install hint's shape with an Allow chip */
#shake-ask{
  position:fixed;left:50%;bottom:calc(14px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);z-index:45;
  display:flex;align-items:center;gap:.8rem;max-width:92vw;
  font-family:var(--font-ui);font-size:13px;color:var(--text);
  background:var(--ink-2);border:1px solid var(--hair-hi);border-radius:14px;padding:.55rem .5rem .55rem 1rem;
  box-shadow:0 12px 40px rgba(0,0,0,.4);--dim:var(--dim-2);--muted:var(--muted-2);
}
#shake-ask .chip{font-family:var(--font-ui);font-weight:700;font-size:10px;letter-spacing:.12em;text-transform:uppercase;min-height:36px;color:var(--accent-text);border-color:var(--accent)}
#shake-ask .x{width:36px;height:36px;border-radius:999px;border:0;background:transparent;color:var(--dim);font-size:18px;cursor:pointer}
#install .x:hover,#whatsnew .x:hover,#shake-ask .x:hover{background:var(--ink-3);color:var(--text)} /* 1.9: the one hover treatment, on the toasts' × too (proposal 25) */
@media (hover:none){ #shake-ask .x{width:44px;height:44px} #shake-ask .chip{min-height:44px} }
/* the hints stack instead of overlapping: install hint at the bottom, the shake hint above it, the toast above both */
/* 1.9: the shake hint names itself and wraps to two lines on a phone, so the toast sits above its measured height (--shake-h, set by app.js) */
body.shake-on #toast,body.shake-on #whatsnew{bottom:calc(24px + var(--shake-h,72px) + env(safe-area-inset-bottom,0px))}
/* 1.11: on the install hint's *measured* height (--install-h, set by app.js), not a constant. The
   constant was 96px, right for Lato at 13px; the default pair moved to Paper and Terminal, whose
   faces set that hint two pixels taller a line, and the shake hint landed on top of it. 14px of
   bottom inset + the hint + a 10px gap. */
body.install-on #shake-ask{bottom:calc(24px + var(--install-h,82px) + env(safe-area-inset-bottom,0px))}
body.install-on.shake-on #toast,body.install-on.shake-on #whatsnew{bottom:calc(34px + var(--install-h,82px) + var(--shake-h,72px) + env(safe-area-inset-bottom,0px))}

/* 1.4: the Shared pill sits beside the view-only pill when both apply */
#shared{margin-left:.35rem}
