
  /* FONTS ARE BUNDLED, NOT FETCHED.
     This was an @import from fonts.googleapis.com for all seven families. That is a
     network request to Google on every cold launch, carrying the device IP and
     User-Agent, in an app whose listing said no network calls. It also meant the app
     rendered in SF Pro offline via the -apple-system fallback, so it looked different
     to itself depending on connectivity.
     All are SIL OFL 1.1 (verified in google/fonts: every one lives under ofl/), so
     redistribution is permitted. Bundled as woff2, latin + latin-ext: 548 KB.
     FIVE families, not the seven the @import requested: Cormorant Garamond and Jost
     had no CSS rule referencing them at all, so the old import was fetching two
     unused families from Google on every launch.
     latin-ext is included deliberately — task text is user-entered, and without it a
     name containing l-stroke or g-breve falls back mid-word to SF Pro.
     Rules below are Google's OWN css2 output with url() repointed at fonts/, so the
     unicode-range and weight declarations are theirs, not hand-written. */
  @font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:300;font-display:swap;src:url('../fonts/HankenGrotesk-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
  @font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:300;font-display:swap;src:url('../fonts/HankenGrotesk-latin.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:'Hanken Grotesk';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/HankenGrotesk-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
  @font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/HankenGrotesk-latin.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:'Hanken Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/HankenGrotesk-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
  @font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/HankenGrotesk-latin.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:'Hanken Grotesk';font-style:normal;font-weight:600;font-display:swap;src:url('../fonts/HankenGrotesk-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
  @font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:600;font-display:swap;src:url('../fonts/HankenGrotesk-latin.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:'Hanken Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/HankenGrotesk-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
  @font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/HankenGrotesk-latin.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;}
  html,body{margin:0;padding:0;overflow-x:hidden;width:100%;height:100%;}
  #app{height:100%;overflow-x:hidden;}
  #app > .tl-wrap{height:100%;box-sizing:border-box;}
  .tl-safetop{position:fixed;top:0;left:0;right:0;height:env(safe-area-inset-top);background:var(--paper);z-index:30;pointer-events:none;}
  .tl-safebot{position:fixed;bottom:0;left:0;right:0;height:max(var(--sab,env(safe-area-inset-bottom)),24px);background:var(--paper);z-index:30;pointer-events:none;}
  .tl-badge-src{display:flex;align-items:center;gap:10px;min-width:0;}
  .tl-badge-emoji{font-size:20px;line-height:1;flex:0 0 auto;width:26px;display:flex;align-items:center;justify-content:center;color:var(--t2);}
  .tl-badge-expand{margin-top:16px;padding-top:16px;border-top:1px solid var(--hair);width:100%;display:flex;align-items:center;justify-content:space-between;background:none;border-left:none;border-right:none;border-bottom:none;font-family:inherit;font-size:14px;font-weight:600;color:var(--accent);cursor:pointer;}
  .tl-badge-expand svg{transition:transform .2s ease;}
  .tl-badge-expand.on svg{transform:rotate(180deg);}
  .tl-badge-list{margin-top:14px;}
  .tida-splash{position:fixed;inset:0;z-index:9999;background:#F3EEE4;display:flex;align-items:center;justify-content:center;padding-top:env(safe-area-inset-top);}
  /* No exit fade: the splash node is removed outright at 1.20s (see the kill timeout at
     the bottom of the file). The old .tida-splash.out rule and its ts-out keyframe are
     gone with it — during that fade the splash stayed hit-testable and swallowed taps,
     because `visibility:hidden` in a keyframe only applies at the very end of the
     interval when the other endpoint is `visible`, not partway through. */
  .ts-lock{display:flex;align-items:center;gap:16px;transform:translateY(-2vh);}
  .ts-leaf{height:92px;width:auto;overflow:visible;}
  .ts-leaf path{stroke-dasharray:1;stroke-dashoffset:1;}
  /* Splash timing (build 12 #1d). Was: stem .85s@.15s, ribs .55s@.85/1.02/1.19/1.36 — last rib
     landed at 1.91s, then 440ms of dead static hold before kill at 2350ms. The whole draw is
     scaled by ~0.628 so the choreography and easing curves are unchanged, just faster: the last
     rib now lands at 1.20s and kill fires there, with no hold. Rib stagger stays even at .11s.
     If you retime these, move setTimeout(kill, 1200) at the bottom of the file to match. */
  .ts-stem{animation:ts-draw .53s cubic-bezier(.4,.0,.2,1) .09s forwards;}
  .ts-b1{animation:ts-draw .34s cubic-bezier(.4,.0,.2,1) .53s forwards;}
  .ts-b2{animation:ts-draw .34s cubic-bezier(.4,.0,.2,1) .64s forwards;}
  .ts-b3{animation:ts-draw .34s cubic-bezier(.4,.0,.2,1) .75s forwards;}
  .ts-b4{animation:ts-draw .34s cubic-bezier(.4,.0,.2,1) .86s forwards;}
  .ts-word{font-family:'Hanken Grotesk',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-weight:800;font-size:52px;line-height:1;color:#0A2A1E;letter-spacing:-.015em;opacity:0;transform:translateX(-10px);animation:ts-word .35s cubic-bezier(.4,.0,.2,1) .18s forwards;}
  @keyframes ts-draw{to{stroke-dashoffset:0;}}
  @keyframes ts-word{to{opacity:1;transform:none;}}
  .tl-root{--paper:#F1F3F1;--ink:#15181B;--t2:#5C6A64;--muted:#717B80;--hair:#E2E6E3;--hair2:#CBD3CE;--surface:#FFFFFF;--accent:#0E7C66;
    --chipbg:rgba(0,0,0,.055);--circ:#C2CBC6;--red:#B23B3B;
    background:var(--paper);color:var(--ink);min-height:100vh;padding-top:env(safe-area-inset-top);padding-bottom:max(var(--sab,env(safe-area-inset-bottom)),24px);padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);box-sizing:border-box;width:100%;overflow-x:hidden;
    font-family:'Hanken Grotesk',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;}
  .tl-wrap{max-width:468px;margin:0 auto;padding:0 16px;}

  .tl-home.anim{animation:fadeUp .26s ease;}
  .tl-head{padding:16px 2px 18px;}
  .tl-title{font-size:30px;font-weight:700;letter-spacing:-.02em;margin:0;}
  .tl-sub{font-size:14px;color:var(--muted);font-weight:500;margin:4px 0 0;}

  .tl-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;padding-bottom:34px;}
  .tl-tile{position:relative;min-width:0;aspect-ratio:1/1;border-radius:22px;padding:16px;display:flex;flex-direction:column;justify-content:space-between;
    border:none;text-align:left;cursor:pointer;color:#1c2422;overflow:visible;transition:transform .12s ease;font-family:inherit;}
  .tl-tile:active{transform:scale(.97);}
  /* BUCKET DELETE. Two beats, and the order is the point: the tile collapses so you can see
     WHICH one went, then the survivors close the gap. 90ms + 120ms — the grid is two columns,
     so half the tiles move diagonally and anything longer reads as busy.
     Reduced motion is already covered: .tl-root * kills every transition, and the JS checks
     the same query and takes the instant path rather than sitting through the delay. */
  .tl-tile.tl-leaving{transition:transform .09s ease-in,opacity .09s ease-in;transform:scale(.86);opacity:0;pointer-events:none;}
  .tl-tile.tl-shifting{transition:transform .12s cubic-bezier(.2,.7,.3,1);}
  /* THE LEDGER, same two beats. A row collapses toward its own left edge rather than its
     centre — a full-width row scaling from the middle reads as a card, which it is not — and
     the transform leaves the space occupied, so the rows below hold still until the node is
     gone and the FLIP slides them. Same 90ms + 120ms. */
  .tl-rowgroup.tl-leaving{transition:transform .09s ease-in,opacity .09s ease-in;transform:scaleX(.92);transform-origin:left center;opacity:0;pointer-events:none;}
  .tl-rowgroup.tl-shifting{transition:transform .12s cubic-bezier(.2,.7,.3,1);}
  .tl-tilebg{position:absolute;inset:0;border-radius:22px;overflow:hidden;}
  .tl-emoji{font-size:20px;line-height:1;position:relative;}
  .tl-tname{font-size:18px;font-weight:600;letter-spacing:-.01em;line-height:1.2;}
  .tl-tmeta{font-size:13px;opacity:.6;font-weight:500;margin-top:1px;display:block;}
  .tl-bar{height:4px;border-radius:99px;background:rgba(0,0,0,.10);overflow:hidden;margin-top:9px;display:block;}
  .tl-bar>i{display:block;height:100%;background:rgba(0,0,0,.4);border-radius:99px;transition:width .25s ease;}
  .tl-tnext{font-size:11.5px;font-weight:600;opacity:.66;margin-top:3px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .tl-tnext.over{color:#B23B3B;opacity:1;}
  .tl-tile.ondark{color:#EEF0F2;}
  .tl-tile.ondark .tl-tmeta,.tl-tile.ondark .tl-tnext{color:#EEF0F2;opacity:.66;}
  .tl-tile.ondark .tl-bar{background:rgba(255,255,255,.16);}
  .tl-tile.ondark .tl-bar>i{background:rgba(255,255,255,.82);}
  .tl-tile.ondark .tl-badge-icon.count{background:#3C4149;color:#fff;box-shadow:none;}
  /* THE RING AND THE SHADOW, CARRIED ACROSS DELIBERATELY. The rule above suppressed them as a
     side effect of the fill being dark; the fills are pale at night now, so it stops firing and
     the badge would get back `box-shadow:0 2px 6px rgba(0,0,0,.25)` and a 2px `var(--paper)`
     ring — which at night is the DARK page, i.e. a dark outline nobody chose around a badge
     that already clears 4.5 on its tile. In light that same ring is cream on a pale tile and
     effectively invisible, so transparent is what carrying it across actually means. */
  .tl-tile.nightpale .tl-badge-icon.count{box-shadow:none;border-color:transparent;}
  .tl-row2-b.ondark .tl-row2-name{color:#EEF0F2;}
  .tl-row2-b.ondark .tl-row2-meta{color:#EEF0F2;opacity:.62;}
  .tl-row2-b.ondark .tl-badge-icon.count{background:#3C4149;color:#fff;box-shadow:none;}
  .tl-row.flash{animation:taskFlash 1.6s ease-out;border-radius:12px;}

  .tl-badgerow{margin:14px 2px 2px;}
  .tl-badge-icon{position:absolute;top:-7px;right:1px;min-width:24px;height:24px;border-radius:12px;background:#E5484D;color:#fff;font-size:13px;font-weight:700;
    display:flex;align-items:center;justify-content:center;padding:0 7px;box-shadow:0 2px 6px rgba(0,0,0,.25);border:2px solid var(--paper);z-index:2;}
  .tl-new,.tl-set{align-items:center;justify-content:center;gap:8px;}
  .tl-new{background:transparent;border:1.5px dashed var(--hair2);color:var(--muted);}
  .tl-new .tl-tname{color:var(--muted);}
  .tl-set{background:var(--surface);border:1px solid var(--hair);color:var(--ink);}
  .tl-set .tl-tname{color:var(--ink);}
  .tl-up{background:var(--deepfam);color:#F4EFE6;align-items:center;justify-content:center;gap:8px;border:none;}
  .tl-up .tl-tname{color:#F4EFE6;}
  /* THE LEDGER'S BOTTOM PADDING. .tl-grid carries padding-bottom:34px and .tl-rows carried
     none, so the last row sat flush against the scroll container's edge — iOS rubber-bands
     past it and settles back with the row clipped. Matched to the grid.
     gap goes to 0 at the same time: the underline IS the separator in a ledger, and a 10px
     gap on top of each row's own 11/10px padding was spacing rows like cards. */
  .tl-rows{display:flex;flex-direction:column;gap:0;padding-bottom:34px;}
  /* The Appearance preview. It sits on --paper like the home screen does, so the ground
     under it changes with Base exactly as the real one will. */
  /* A portrait miniature of a phone. The inner column is laid out at a real device width
     (390, matching .tl-wrap's 16px gutters) and scaled to the frame: 168/390 = .4308.
     HEIGHT IS THE ONLY LEVER THAT ADDS CONTENT. Measured, not estimated: the six fixtures
     run 876pt and the bottom row ended at 842, against 845 visible — it fit by 3pt, which
     is why it clipped on device. Scaling the frame in both axes changes nothing, because
     visible = frameH x innerW / frameW; narrowing innerW is worse still, since the header
     and hero barely shrink with width while visible height falls faster. So: 384 tall,
     showing 891pt. The whole document fits with 15pt spare and the scale is untouched,
     which is what keeps a tile at 75px on screen. Ratio 0.438 against an iPhone's 0.461. */
  .tl-pvwrap{display:flex;justify-content:center;margin:2px 0 8px;}
  .tl-pvphone{width:129px;height:295px;border-radius:20px;overflow:hidden;position:relative;
    background:var(--paper);border:1px solid var(--hair2);pointer-events:none;
    box-shadow:0 1px 4px rgba(0,0,0,.07);}
  .tl-pvscale{position:absolute;top:0;left:0;width:390px;box-sizing:border-box;padding:0 16px;
    transform:scale(.3308);transform-origin:top left;}
  .tl-pvscale .tl-home{min-height:0;}
  /* TWO PREVIEWS AS THE CONTROL: 129pt frames side by side (0.3308 — the last scale at which the
     two views still read as two layouts), the chosen one ringed, the other at 60%. */
  .tl-pvtwo{gap:12px;align-items:flex-start;}
  .tl-pvcell{display:flex;flex-direction:column;align-items:center;gap:5px;cursor:pointer;-webkit-tap-highlight-color:transparent;}
  .tl-pvcell.sel .tl-pvphone{box-shadow:0 0 0 2px var(--accent);border-color:transparent;}
  .tl-pvcell.mute .tl-pvphone{opacity:.6;}
  .tl-pvlab{font-size:13px;font-weight:600;color:var(--muted);}
  .tl-pvcell.sel .tl-pvlab{color:var(--ink);}
  .tl-headrow{display:flex;align-items:center;justify-content:space-between;gap:10px;}
  .tl-brand{display:flex;align-items:center;gap:9px;min-width:0;}
  .tl-logomark{height:30px;width:auto;color:#2E6B52;flex:0 0 auto;display:block;margin-left:16px;}
  .tl-headdate{flex:1;min-width:0;text-align:center;font-size:14px;font-weight:600;letter-spacing:-.01em;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 10px;}
  .tl-toggle.disabled{opacity:.42;}
  .tl-toggle.disabled .tl-switch{pointer-events:none;}
  .tl-root.tnight .tl-logomark{color:#5AA588;}
  .tl-topicons{display:flex;gap:8px;flex:0 0 auto;}
  .tl-topic{width:38px;height:38px;border-radius:50%;background:var(--surface);border:1px solid var(--hair);color:var(--muted);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;}
  .tl-hero{display:block;width:100%;text-align:left;border:none;cursor:pointer;border-radius:22px;padding:18px 19px;position:relative;margin-bottom:12px;font-family:inherit;}
  .tl-hrow{display:flex;align-items:center;gap:11px;}
  .tl-hemoji{font-size:28px;line-height:1;flex:0 0 auto;}
  /* THE HERO FOLLOWS ITS OWN GROUND, like .tl-tile above it, and for the same reason.
     These four rules read var(--ink) and var(--muted) — PAGE variables that flip to light in
     dark mode. That was invisible while the hero's fill was dark at night, because it flipped
     with them. The fill is pale now for the five hue themes, and the text did not follow:
     white on peach. .tl-tile never had the bug because it hardcodes #1c2422, which does not
     flip; the hero simply never got the same treatment.
     Fixed values, not variables. #1c2422 is the tile ink (light --ink is #1F1B16 / #191A1C,
     so the change measures 9.94 -> 9.20 on a light hero: both near-black, imperceptible).
     The muted alpha is .50 because that reproduces what var(--muted) measured on these fills
     — 2.72 against 2.70 — rather than being picked by eye.
     .ondark still wins for a DARK hero, which is Mono's, so Mono keeps its light text. */
  .tl-hname{font-size:23px;font-weight:600;letter-spacing:-.01em;color:#1c2422;}
  .tl-hero.ondark .tl-hname{color:#ECEEF0;}
  .tl-hero-empty{font-size:15px;font-weight:500;color:rgba(28,36,34,.62);margin-top:12px;line-height:1.45;}
  .tl-hero.ondark .tl-hero-empty{color:rgba(255,255,255,.6);}
  .tl-hstats{display:flex;margin-top:14px;}
  .tl-hstat{flex:1;padding-right:12px;min-width:0;}
  .tl-hstat+.tl-hstat{border-left:1px solid rgba(0,0,0,.10);padding-left:15px;}
  .tl-hero.ondark .tl-hstat+.tl-hstat{border-left-color:rgba(255,255,255,.14);}
  .tl-hstat .v{font-size:19px;font-weight:700;letter-spacing:-.01em;color:#1c2422;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .tl-hstat .l{font-size:10px;font-weight:600;letter-spacing:.03em;text-transform:uppercase;color:rgba(28,36,34,.5);margin-top:2px;}
  .tl-hero.ondark .tl-hstat .v{color:#ECEEF0;} .tl-hero.ondark .tl-hstat .l{color:rgba(255,255,255,.45);}
  .tl-hstat .v.over{color:#B23B3B;} .tl-hero.ondark .tl-hstat .v.over{color:#E0736B;}
  .tl-hbar{height:6px;border-radius:99px;background:rgba(0,0,0,.10);margin-top:15px;overflow:hidden;}
  .tl-hbar>i{display:block;height:100%;border-radius:99px;background:rgba(0,0,0,.42);}
  .tl-hero.ondark .tl-hbar{background:rgba(255,255,255,.16);} .tl-hero.ondark .tl-hbar>i{background:rgba(255,255,255,.82);}
  .tl-hero .tl-badge-icon.count{top:-9px;right:1px;}
  .tl-reord{height:36px;width:36px;border-radius:50%;background:var(--surface);border:1px solid var(--hair);color:var(--t2);display:flex;align-items:center;justify-content:center;cursor:pointer;flex:0 0 auto;}
  .tl-reord:hover{color:var(--ink);}
  .tl-tile,.tl-row2,.tl-rowgroup{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;user-select:none;-webkit-user-select:none;}
  .tl-rowgroup.lift{z-index:50;position:relative;}
  .tl-rowgroup.lift .tl-row2{box-shadow:0 14px 30px rgba(0,0,0,.22);}
  .tl-row2{display:flex;align-items:center;gap:13px;padding:12px 14px;background:var(--surface);border:1px solid var(--hair);border-radius:14px;width:100%;text-align:left;cursor:pointer;position:relative;}
  .tl-row2-box{width:38px;height:38px;border-radius:10px;flex:0 0 auto;display:grid;place-items:center;font-size:19px;}
  .tl-row2-box.ic{background:var(--chipbg);color:var(--ink);}
  .tl-row2-box.dash{background:transparent;border:1.5px dashed var(--hair2);color:var(--muted);}
  .tl-row2-main{flex:1;min-width:0;}
  .tl-row2-name{font-weight:700;font-size:15px;color:var(--ink);display:block;line-height:1.25;}
  .tl-row2-meta{font-size:12.5px;color:var(--muted);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .tl-row2 .tl-badge-icon{position:static;top:auto;right:auto;margin-left:auto;box-shadow:none;border:none;}
  .tl-row2-act .tl-row2-name{font-weight:600;}
  .tl-row2-b{color:#1c2422;border:none;}
  .tl-row2-b .tl-row2-name{color:#1c2422;}
  .tl-row2-b .tl-row2-meta{color:#1c2422;opacity:.62;}
  .tl-row2-emoji{font-size:22px;line-height:1;flex:0 0 auto;width:30px;text-align:center;}
  .tl-rowgroup{display:flex;flex-direction:column;}
  /* ---- ROWS. The card row: surface, hair border, 14pt radius (the .tl-row2 base above), a
     tinted glyph square on the left, name and meta, the count badge right. No underline.
     --rowtint is the bucket's colour. In BOLD the row takes the bucket's fill (--rowfill,
     .bold) and the square becomes a WHITE WELL: a tinted square on a filled row measured 1.00
     and vanished. Ink on a Bold row is the tile's — dark on a pale fill, light on a dark one
     (.ondark) — never the theme's, which at night is light and would sit on a pale fill. ---- */
  .tl-row2{padding:10px 12px;}
  .tl-row2-b{color:var(--ink);border:1px solid var(--hair);}   /* the card's hair border; the old .tl-row2-b rule above removed it for the ledger */
  .tl-row2-b .tl-row2-name,.tl-row2-act .tl-row2-name{color:var(--ink);font-weight:600;}
  .tl-row2-b .tl-row2-meta{color:var(--muted);opacity:1;}
  .tl-row2-b .tl-row2-emoji{width:34px;height:34px;border-radius:9px;display:flex;align-items:center;justify-content:center;background:var(--rowtint,var(--chipbg));}
  .tl-row2-b.bold{background:var(--rowfill,var(--surface));border-color:transparent;}
  .tl-row2-b.bold .tl-row2-emoji{background:rgba(255,255,255,.22);}
  .tl-row2-b.bold .tl-row2-name{color:#1c2422;}
  .tl-row2-b.bold .tl-row2-meta{color:#1c2422;opacity:.72;}
  .tl-row2-b.bold.ondark .tl-row2-name{color:#EEF0F2;}
  .tl-row2-b.bold.ondark .tl-row2-meta{color:#EEF0F2;opacity:.66;}
  .tl-row2-act .tl-row2-box{background:none!important;color:var(--t2)!important;width:24px;}
  /* The original .tl-rowsub carries margin-top:8px and padding:6px 8px. This override
     replaced the whole shorthand and zeroed both, so expanded content sat FLUSH against the
     underline while the next row still contributed its own 11px below — the uneven gap in
     the screenshot. The top gap is restored; only the card styling is stripped. */
  .tl-rowsub{background:none!important;border:none!important;border-radius:0!important;padding:10px 0 2px 26px!important;margin-top:0!important;}
  .tl-rowgroup+.tl-rowgroup{margin-top:5px;}
  /* tasks as flat lines: hairline between, nothing filled */
  .tl-rowgroup .tl-subwrap{background:none;border-radius:0;}
  .tl-rowgroup .tl-subt.tl-subrow{background:none;border:none;border-radius:0;}
  .tl-rowgroup .tl-chip{background:none;padding:0 0 0 8px;color:var(--muted);font-weight:600;}
  .tl-rowgroup .tl-chip.over{color:var(--red);}
  .tl-row2-open{display:flex;align-items:center;gap:13px;flex:1;min-width:0;background:none;border:none;padding:0;margin:0;cursor:pointer;color:inherit;text-align:left;font-family:inherit;}
  .tl-rowsub{background:var(--surface);border:1px solid var(--hair);border-radius:14px;margin-top:8px;padding:6px 8px;display:flex;flex-direction:column;position:relative;}
  .tl-subwrap{position:relative;overflow:hidden;border-radius:9px;}
  .tl-subrow{background:var(--surface);position:relative;z-index:1;will-change:transform;}
  .tl-subrow.lift{z-index:30;background:var(--surface);border-radius:10px;box-shadow:0 10px 26px rgba(0,0,0,.2);}
  .tl-handle.sm{flex:0 0 34px;height:34px;}
  .tl-subadd{display:flex;align-items:center;gap:8px;padding:6px 4px 2px;}
  /* Focus ring follows the field's own rounded shape. `outline` is not reliably rounded
     to match border-radius in WebKit, so the accent ring read as a square against a
     rounded field — the only square corners in the app. box-shadow always follows
     border-radius, so no radius is hardcoded here: the ring inherits whatever the input
     has, which is 12px from `.tl-subadd input` further down (that rule outranks
     `.tl-subadd-in`, so the 9px on the line above never applies to the input).
     Specificity (0,2,0) is deliberate — it has to beat the app-wide
     `input:focus-visible` outline, which text inputs always match when focused. */
  .tl-subadd-in:focus,.tl-subadd-in:focus-visible{outline:none;box-shadow:0 0 0 2px var(--accent);}
  .tl-aseg{display:flex;background:var(--chipbg);border-radius:11px;padding:3px;gap:2px;margin:0 0 16px;}
  .tl-asegrow{display:flex;align-items:center;gap:10px;margin:0 0 16px;}
  /* THE CALENDAR FILTER CHIPS. Off = muted and faded, on = ink; "Show all" in accent ink (text, not a fill). */
  .tl-calchips{display:flex;flex-wrap:wrap;gap:6px;margin:-6px 0 14px;}
  .tl-calchip{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 11px;border-radius:15px;border:1px solid var(--hair);background:var(--surface);color:var(--muted);font-family:inherit;font-weight:600;font-size:13px;cursor:pointer;opacity:.6;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;user-select:none;-webkit-user-select:none;}
  .tl-calchip.on{color:var(--ink);opacity:1;border-color:var(--hair2);}
  .tl-calchip.all{color:var(--accent);opacity:1;}
  .tl-calchip svg{flex:0 0 auto;}
  .tl-asegrow .tl-aseg{flex:1;margin:0;}
  .tl-aseg .tl-segb{flex:1;text-align:center;}
  .tl-calnav{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;}
  .tl-caltitle{font-weight:700;font-size:15.5px;color:var(--ink);}
  .tl-navb{background:var(--surface);border:1px solid var(--hair);border-radius:9px;width:36px;height:36px;display:grid;place-items:center;color:var(--ink);cursor:pointer;}
  .tl-navb.disabled{opacity:.32;pointer-events:none;cursor:default;}
  .tl-sresult.virtual{cursor:default;opacity:.82;}
  .tl-sresult.virtual.tappable{cursor:pointer;}
  .tl-skiphead{display:flex;align-items:center;gap:9px;margin:2px 0 6px;}
  .tl-skipglyph{color:var(--accent);display:flex;flex:0 0 auto;}
  .tl-skipdate{font-size:14px;font-weight:600;color:var(--muted);margin:0 0 6px;display:flex;align-items:center;gap:6px;}
  .tl-recurlead{width:23px;height:23px;display:flex;align-items:center;justify-content:center;color:var(--t2);flex:0 0 auto;}
  .tl-week{display:flex;flex-direction:column;gap:10px;}
  .tl-weekday{background:var(--surface);border:1px solid var(--hair);border-radius:12px;padding:9px 11px;}
  .tl-weekday.today{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent);}
  .tl-weekday-h{display:flex;align-items:baseline;gap:8px;margin-bottom:3px;}
  .tl-wd-name{font-weight:700;font-size:13.5px;color:var(--ink);}
  .tl-wd-num{font-size:12px;color:var(--muted);font-weight:600;}
  .tl-weekday.today .tl-wd-name{color:var(--accent);}
  .tl-wd-empty{color:var(--muted);opacity:.5;font-size:13px;padding:3px 2px;}
  .tl-monthhead{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:5px;margin-bottom:6px;}
  .tl-mh{text-align:center;font-size:11px;font-weight:700;color:var(--muted);}
  /* minmax(0,1fr) and min-width:0 — CANDIDATE, UNCONFIRMED: on the iPad, resizing panel 2 in month
     view scrolled sideways instead of refitting; Chromium refits. The theory is WebKit's automatic
     minimum width for a grid item with an aspect ratio in a plain 1fr track. Confirm on the device. */
  .tl-month{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:5px;}
  .tl-mcell{min-width:0;aspect-ratio:1;background:var(--surface);border:1px solid transparent;border-radius:10px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;cursor:pointer;font-family:inherit;padding:0;}
  .tl-mcell.empty{background:none;cursor:default;}
  .tl-mnum{font-size:13px;font-weight:600;color:var(--ink);}
  .tl-mcell.today .tl-mnum{background:var(--ink);color:var(--paper);border-radius:50%;width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;font-weight:700;}
  .tl-mcell.sel{border-color:var(--accent);background:var(--chipbg);}
  .tl-mdot{min-width:7px;height:14px;border-radius:7px;background:var(--accent);font-size:9.5px;line-height:1;color:var(--paper);font-weight:700;display:flex;align-items:center;justify-content:center;padding:0 4px;}
  .tl-mselist{margin-top:18px;}
  /* THE PINNED MONTH: the single-column month is a column that fills its scroller. Everything
     above the selected day's list is pinned (flex:none), the list takes the remainder and
     scrolls. The grid cannot scroll off. The landscape month (side column) is not this. */
  .tl-bview.tl-month-pinned{display:flex;flex-direction:column;height:100%;min-height:0;}
  .tl-month-pinned .tl-bhead{flex:0 0 auto;}
  .tl-month-pinned .tl-list{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;padding-bottom:0;}
  .tl-month-pinned .tl-list > *{flex:0 0 auto;}
  .tl-month-pinned .tl-mselist{flex:1 1 auto;min-height:0;overflow:auto;-webkit-overflow-scrolling:touch;padding-bottom:20px;}
  .tl-mselhead{font-weight:700;font-size:14.5px;color:var(--ink);margin-bottom:8px;}
  .tl-seg{display:inline-flex;background:var(--chipbg);border-radius:10px;padding:3px;gap:2px;flex:0 0 auto;}
  .tl-segb{border:none;background:transparent;color:var(--muted);font-weight:600;font-size:13px;padding:6px 12px;border-radius:8px;cursor:pointer;font-family:inherit;}
  .tl-segb.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 3px rgba(0,0,0,.12);}

  .tl-bview.anim{animation:slideIn .26s ease;}
  .tl-bview-tasks.anim{animation:tlFade .2s ease;}
  .tl-bhead{display:flex;align-items:center;gap:4px;padding:18px 0 8px;}
  .tl-ico{height:40px;width:40px;border-radius:50%;border:none;background:transparent;color:var(--ink);display:flex;align-items:center;justify-content:center;cursor:pointer;flex:0 0 auto;}
  .tl-ico:active{background:rgba(0,0,0,.05);}
  .tl-btitle{font-size:24px;font-weight:700;letter-spacing:-.02em;flex:1;border:none;background:transparent;color:var(--ink);padding:4px 2px;text-align:left;font-family:inherit;cursor:text;min-width:0;}
  .tl-btitle.ph{color:var(--muted);}
  .tl-mono{display:inline-flex;align-items:center;justify-content:center;font-weight:600;letter-spacing:.01em;line-height:1;}
  .tl-bcolors{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:2px 2px 12px;}
  .tl-bcolab{font-size:12px;font-weight:600;color:var(--muted);margin-right:2px;}
  .tl-bicons{padding-top:0;}
  /* Twenty-one chips do not belong on a horizontal scroller: at 34px plus a gap that is ~900px
     of scrubbing to reach the last one, and none of the set is visible at rest. A wrapping grid
     shows all of it in three rows. The label moves above the grid rather than beside it. */
  .tl-iconpick{display:block;padding:2px 2px 12px;}
  .tl-iconpick .tl-bcolab{display:block;margin-bottom:8px;}
  .tl-icongrid{display:grid;grid-template-columns:repeat(auto-fill,34px);gap:8px;justify-content:space-between;}
  .tl-bicon-btn{flex:0 0 auto;scroll-snap-align:start;width:34px;height:34px;border-radius:10px;border:1.5px solid transparent;background:var(--paper);font-size:18px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;}
  .tl-bicon-btn.sel{border-color:var(--ink);}
  .tl-tedit{font-size:24px;font-weight:700;letter-spacing:-.02em;flex:1;border:none;border-bottom:2px solid var(--accent);background:transparent;color:var(--ink);padding:3px 2px;outline:none;min-width:0;font-family:inherit;}
  .tl-bprog{font-size:13px;color:var(--muted);font-weight:500;padding:0 2px 2px;display:flex;align-items:center;justify-content:space-between;gap:12px;}
  .tl-clearcomp{display:inline-flex;align-items:center;gap:5px;background:none;border:none;font:inherit;font-size:13px;font-weight:600;color:var(--t2);cursor:pointer;padding:2px 0;flex:0 0 auto;}
  .tl-clearcomp:hover{color:var(--red);}
  .tl-clearcomp svg{color:var(--red);}
  .tl-hinttip{font-size:12px;color:var(--muted);padding:0 2px 14px;opacity:.85;line-height:1.4;}

  .tl-list{padding-bottom:20px;min-height:46vh;position:relative;}
  .tl-bview-tasks{display:flex;flex-direction:column;height:100%;}
  .tl-bview-tasks > *{flex:0 0 auto;}
  .tl-bview-tasks > .tl-list{flex:1 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;touch-action:pan-y;}
  /* NO SEPARATORS between task rows. The 46px min-height and the row padding carry the
     rhythm on their own; the hairline was doing the same job twice. Ledger subrows never had
     one — .tl-rowgroup .tl-subt.tl-subrow already sets border:none — so this is the only
     rule that had to go. The Ledger's .tl-row2 underline stays: that is the ledger rule
     itself, not a separator between tasks. */
  .tl-rowwrap{position:relative;overflow:hidden;}
  .tl-row{display:flex;align-items:center;min-height:46px;cursor:pointer;background:var(--paper);position:relative;z-index:1;
    touch-action:pan-y;user-select:none;-webkit-user-select:none;}
  .tl-row.lift{z-index:30;background:var(--surface);border-radius:12px;box-shadow:0 10px 28px rgba(0,0,0,.2);}
  .tl-check{flex:0 0 44px;height:44px;display:flex;align-items:center;justify-content:center;border:none;background:none;cursor:pointer;padding:0;}
  .tl-circ{width:23px;height:23px;border-radius:50%;border:2px solid var(--circ);display:flex;align-items:center;justify-content:center;transition:background .18s ease,border-color .18s ease,transform .12s ease;}
  .tl-check:active .tl-circ{transform:scale(.86);}
  /* color:var(--paper) IS THE APP'S RULE FOR A MARK ON AN ACCENT FILL, and .tl-subcirc and
     .tl-switch i already followed it. This one drew icon('check', …, '#fff') from six call
     sites instead, which is 2.93 in sage dark, 2.18 in bloom dark and 1.23 in mono dark —
     ACCENT_DARK.mono is #E7E8E9, so a completed task's tick was white on near-white. The
     floor for a check glyph is 3.0, not 4.5: WCAG 1.4.11 governs graphical objects and state
     indicators, and 4.5 is the body-text floor. All three failed the correct floor anyway.
     The colour lives HERE rather than at the call sites so a seventh row cannot reintroduce
     it — test/markcontrast sweeps for exactly that. */
  .tl-circ.on{background:var(--accent);border-color:var(--accent);color:var(--paper);}
  /* A backup row's swipe-to-delete. Same shape and same gesture as a task's, so there is
     nothing new to learn — the face slides and the action is revealed beneath it. */
  /* A premium group's header. Full width and 46px tall — the whole row is the target, which
     is what stops one direction of the toggle being unreachable. */
  .tl-pmgrp{width:100%;display:flex;align-items:center;gap:8px;min-height:46px;padding:0 2px;
    border:none;background:none;font-family:inherit;cursor:pointer;text-align:left;color:var(--ink);}
  .tl-pmgrp-t{flex:1;min-width:0;font-size:15px;font-weight:600;}
  .tl-pmgrp-m{color:var(--muted);font-weight:500;}
  .tl-pmgrp-m::before{content:" · ";}
  .tl-pmgrp-c{flex:0 0 auto;color:var(--muted);display:flex;transition:transform .18s ease;}
  .tl-pmgrp.open .tl-pmgrp-c{transform:rotate(180deg);}
  /* A row that opens a sheet, not a group: the chevron points the way out. */
  .tl-pmgrp.link .tl-pmgrp-c{transform:rotate(-90deg);}
  .tl-pmgrp-b{padding-top:4px;padding-bottom:10px;}
  /* The divider belongs BETWEEN groups, so it is drawn by the second one onwards rather
     than by each group unconditionally — one card, no trailing rule under the last row.
     Same 1px var(--hair) the Appearance rows use. */
  .tl-pmgrp-w + .tl-pmgrp-w{border-top:1px solid var(--hair);}
  .tl-bkrow{position:relative;overflow:hidden;}
  .tl-bkdel{position:absolute;inset:0;display:flex;align-items:center;justify-content:flex-end;padding-right:4px;}
  .tl-bkdelbtn{display:flex;align-items:center;gap:6px;height:100%;padding:0 14px;border:none;background:none;color:var(--red);font-family:inherit;font-weight:600;font-size:13px;cursor:pointer;}
  /* touch-action:pan-y is what makes the horizontal swipe REACH us. Without it the default
     is auto, iOS claims a horizontal drag inside a scrolling sheet as a pan, fires
     pointercancel instead of pointerup, and the gesture never completes — which is exactly
     what happened on device while the harness saw nothing, because it never bound the
     listener at all. Copied from .tl-row, where the task swipe has always worked. */
  .tl-bkface{position:relative;background:var(--surface);transition:transform .18s ease;
    touch-action:pan-y;user-select:none;-webkit-user-select:none;}
  .tl-bkrow.open .tl-bkface{transform:translateX(-104px);}
  .tl-circ.pop{animation:pop .42s ease;}
  .tl-body{flex:1;display:flex;align-items:center;min-width:0;padding:7px 8px 7px 2px;}
  .tl-text{font-size:16px;color:var(--ink);font-weight:500;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .tl-text.parent{color:var(--ink);font-weight:600;}
  .tl-text.done{color:var(--muted);text-decoration:line-through;font-weight:500;}
  .tl-text.empty{color:#A9B2AD;}
  .tl-note-dot{width:6px;height:6px;border-radius:50%;background:var(--hair2);margin-left:8px;flex:0 0 auto;}
  .tl-bell{margin-left:8px;color:var(--muted);display:inline-flex;flex:0 0 auto;}
  .tl-chip{font-size:12px;font-weight:600;color:var(--muted);background:var(--chipbg);padding:3px 8px;border-radius:8px;margin-left:8px;white-space:nowrap;flex:0 0 auto;}
  .tl-chip.over{color:var(--red);background:rgba(178,59,59,.1);}
  .tl-chip.rep{color:var(--paper);background:var(--accent);}
  .tl-toast{position:fixed;left:50%;bottom:96px;transform:translate(-50%,16px);background:#1f2724;color:#fff;font-size:13.5px;font-weight:600;letter-spacing:.01em;padding:11px 18px;border-radius:13px;box-shadow:0 10px 30px rgba(0,0,0,.28);opacity:0;pointer-events:none;transition:opacity .26s ease,transform .26s ease;z-index:9999;max-width:82%;text-align:center;}
  .tl-toast{display:flex;align-items:center;gap:16px;}
  .tl-toast.act{pointer-events:auto;}
  .tl-toast-act{background:none;border:none;color:#fff;font:inherit;font-weight:800;letter-spacing:.03em;cursor:pointer;padding:2px 0;flex:0 0 auto;border-left:1px solid rgba(255,255,255,.25);padding-left:16px;}
  .tl-badge-icon.count{background:rgba(18,22,20,.34);box-shadow:none;}
  .tl-quick{display:flex;align-items:center;gap:8px;background:var(--surface);border:1px solid var(--hair);border-radius:16px;padding:5px 5px 5px 16px;margin:0 0 18px;}
  .tl-qin{flex:1;border:none;background:transparent;color:var(--ink);font:inherit;font-size:15px;outline:none;min-width:0;padding:9px 0;}
  .tl-qin::placeholder{color:var(--muted);}
  /* Here the visible field is the WRAPPER, not the input: .tl-quick carries the border
     and the 16px radius, and .tl-qin has neither (measured: input border-radius 0px).
     So the app-wide `input:focus-visible` outline drew a square ring around a
     zero-radius box sitting inside a rounded container — the reason this one control
     looked wrong while the others were fine.
     The ring goes on the wrapper via :focus-within so it follows the shape actually on
     screen, and as with .tl-subadd-in no radius is hardcoded — box-shadow inherits
     .tl-quick's own 16px. :focus-within (not :has) because :has needs Safari 15.4 and
     the deployment target is iOS 15.0.
     Specificity (0,2,0) on the input rule is deliberate: it must outrank the app-wide
     input:focus-visible outline, which text inputs always match when focused. */
  .tl-quick:focus-within{box-shadow:0 0 0 2px var(--accent);}
  .tl-qin:focus,.tl-qin:focus-visible{outline:none;}
  .tl-qbtn{height:38px;width:38px;border-radius:50%;border:none;background:var(--accent);color:var(--paper);display:flex;align-items:center;justify-content:center;cursor:pointer;flex:0 0 auto;}
  .tl-qbtn:disabled{opacity:.38;}

  .tl-bexp{height:40px;width:40px;border-radius:50%;border:none;background:transparent;color:var(--t2);display:flex;align-items:center;justify-content:center;cursor:pointer;flex:0 0 auto;}
  .tl-expbtn{display:flex;align-items:center;gap:14px;width:100%;text-align:left;background:transparent;border:none;border-bottom:1px solid var(--hair);color:var(--ink);font:inherit;font-size:16px;font-weight:600;padding:15px 2px;cursor:pointer;}
  .tl-expbtn:last-child{border-bottom:none;}
  .tl-expbtn .xi{height:36px;width:36px;border-radius:11px;background:var(--chipbg);display:flex;align-items:center;justify-content:center;color:var(--ink);flex:0 0 auto;}
  .tl-expbtn .xsub{display:block;color:var(--muted);font-size:12.5px;font-weight:500;margin-top:1px;}
  .tl-toast.show{opacity:1;transform:translate(-50%,0);}
  .tl-hint{position:absolute;top:0;bottom:0;display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600;color:var(--accent);opacity:0;pointer-events:none;}
  .tl-hint-l{left:10px;} .tl-hint-r{right:10px;}
  .tl-hint-l.del,.tl-hint-r.del{color:var(--red);}
  .tl-dragbadge{position:absolute;right:12px;top:50%;transform:translateY(-50%);background:var(--accent);color:var(--paper);font-size:12px;font-weight:700;border-radius:9px;padding:2px 7px;}
  .tl-dropline{position:absolute;left:6px;right:6px;height:2.5px;background:var(--accent);border-radius:2px;z-index:25;pointer-events:none;}
  .tl-dropline::before{content:"";position:absolute;left:-3px;top:50%;transform:translateY(-50%);width:9px;height:9px;border-radius:50%;background:var(--accent);}
  .tl-handle{flex:0 0 40px;height:44px;display:flex;align-items:center;justify-content:center;border:none;background:none;color:var(--accent);opacity:.85;cursor:grab;touch-action:none;padding:0;}
  .tl-collapse{flex:0 0 30px;height:44px;display:flex;align-items:center;justify-content:center;border:none;background:none;color:var(--muted);padding:0;cursor:pointer;}
  .tl-collapse svg{transition:transform .18s ease;}
  .tl-collapse.col svg{transform:rotate(-90deg);}
  .tl-pastebox{width:100%;min-height:150px;box-sizing:border-box;border-radius:14px;border:1px solid var(--hair);background:var(--paper);color:var(--ink);font:inherit;font-size:15px;line-height:1.5;padding:12px 14px;resize:none;outline:none;margin-bottom:12px;}
  .tl-pastebox::placeholder{color:var(--muted);}
  .tl-handle:active{cursor:grabbing;opacity:1;}
  .tl-tile.lift{z-index:50;box-shadow:0 16px 36px rgba(0,0,0,.25);}
  .tl-tile.droptarget{outline:2.5px dashed var(--accent);outline-offset:3px;}
  .tl-searchin{flex:1;height:42px;border:1px solid var(--hair);border-radius:12px;background:var(--surface);padding:0 14px;font-size:16px;color:var(--ink);outline:none;font-family:inherit;}
  .tl-searchin:focus{border-color:var(--accent);}
  .tl-sresult{width:100%;display:flex;align-items:center;gap:12px;padding:11px 4px;border:none;border-bottom:1px solid var(--hair);background:transparent;cursor:pointer;font-family:inherit;text-align:left;}
  .tl-sresult:active{background:rgba(0,0,0,.03);}
  .tl-sres-main{flex:1;min-width:0;display:flex;flex-direction:column;}
  .tl-sres-text{font-size:16px;color:var(--ink);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .tl-sres-text.done{color:var(--muted);text-decoration:line-through;}
  /* Flex, because these lines now hold a glyph and a name rather than an emoji and a name.
     An SVG has no baseline to sit on, so centring is done by the container. This is the rule
     the event row already used; it applies to every row now instead of only to events. */
  .tl-sres-sub{font-size:12.5px;color:var(--muted);margin-top:1px;display:flex;align-items:center;gap:5px;min-width:0;}
  .tl-sres-sub svg,.tl-sres-sub .tl-mono{flex:0 0 auto;}
  .tl-agsec{margin-top:18px;}
  .tl-agsec h2{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);margin:0 0 2px;padding-left:4px;}
  .tl-agsec h2.over{color:var(--red);}
  .tl-vidcard{width:100%;display:flex;align-items:center;gap:14px;border:none;background:transparent;cursor:pointer;font-family:inherit;padding:0;}
  /* color: is what the SVG inside inherits through stroke="currentColor". The mark used to
     carried a hardcoded white stroke inline in the markup — the same accent-filled white as the twelve CSS
     rules, but invisible to a stylesheet check because it was never in the stylesheet. */
  .tl-vidplay{width:54px;height:54px;border-radius:14px;background:var(--accent);color:var(--paper);display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
  .tl-vidcap{font-size:15px;font-weight:600;color:var(--ink);}
  .tl-video{aspect-ratio:16/9;border-radius:16px;background:linear-gradient(135deg,var(--hair),var(--hair2));display:flex;align-items:center;justify-content:center;margin-top:4px;}
  .tl-tut{margin-top:8px;}
  .tl-tutrow{font-size:14px;color:var(--ink);padding:9px 0;border-bottom:1px solid var(--hair);line-height:1.45;}
  .tl-tutrow:last-child{border-bottom:none;}
  .tl-tutrow b{font-weight:700;}
  .tl-gd{margin-top:6px;}
  .tl-gd-lede{font-size:14.5px;color:var(--muted);margin:2px 2px 4px;line-height:1.5;}
  .tl-gd-eyebrow{font-size:11.5px;letter-spacing:.10em;text-transform:uppercase;color:var(--accent);font-weight:700;margin:22px 0 10px;}
  .tl-gd-card{background:var(--surface);border:1px solid var(--hair);border-radius:16px;padding:12px 12px 15px;margin:0 0 12px;}
  .tl-gd-stage{background:var(--paper);border-radius:12px;width:100%;display:block;}
  .tl-gd-stage text{font-family:inherit;}
  .tl-gd-card h3{font-size:16px;color:var(--ink);margin:13px 2px 2px;font-weight:600;letter-spacing:-.01em;}
  .tl-gd-card p{font-size:14px;color:var(--t2);margin:0 2px;line-height:1.5;}
  .tl-gd-card p .k{color:var(--accent);font-weight:600;}
  .tl-gd-code{background:var(--chipbg);border-radius:6px;padding:1px 6px;font-size:13px;color:var(--ink);font-weight:500;white-space:nowrap;}
  .tl-gd-foot{margin-top:16px;padding-top:14px;border-top:1px solid var(--hair);color:var(--muted);font-size:13px;display:flex;align-items:center;gap:8px;}
  .tl-gd-foot svg{width:15px;height:15px;color:var(--accent);flex:none;}
  .tl-gd-stage .row{fill:var(--surface);stroke:var(--hair);}
  .tl-gd-stage .rowghost{fill:none;stroke:var(--hair2);}
  .tl-gd-stage .acc{fill:var(--accent);}
  /* Marks drawn ON an .acc shape. --paper, never #fff: the accent is #E7E8E9 in dark Mono. */
  .tl-gd-stage .onacc{stroke:var(--paper);}
  .tl-gd-stage .accs{stroke:var(--accent);}
  .tl-gd-stage .cbox{fill:none;stroke:var(--accent);}
  .tl-gd-stage .ln{fill:var(--hair2);}
  .tl-gd-stage .ln2{fill:var(--circ);}
  /* WORDS, where .ln and .ln2 used to be a bar standing in for a task name. Same three roles
     the app itself uses on a row: ink for a task, muted for one that is finished (with
     text-decoration on the element, which self-sizes to the string), and --paper for a name
     drawn ON an accent fill — the fill sibling of .onacc, and --paper for the same reason. */
  .tl-gd-stage .tx{fill:var(--ink);}
  .tl-gd-stage .txm{fill:var(--muted);}
  .tl-gd-stage .onaccf{fill:var(--paper);}
  .tl-gd-stage .hdl{stroke:var(--circ);}
  .tl-gd-stage .strk{stroke:var(--muted);}
  .tl-gd-stage .red{fill:var(--red);}
  .tl-gd-stage .reds{stroke:var(--red);}
  .tl-gd-stage .badge{fill:var(--chipbg);}
  .tl-gd-stage .btxt{fill:var(--accent);}
  .tl-gd-stage .seg{fill:var(--accent);}
  .tl-gd-stage .segtxt{fill:var(--muted);}
  .tl-gd-stage .segon{fill:var(--paper);}
  .tl-gd-stage .pill{fill:var(--chipbg);}
  .tl-gd-stage .phone{fill:var(--surface);stroke:var(--ink);}
  .tl-pm-head{display:flex;align-items:center;gap:13px;margin:2px 0 2px;}
  .tl-pm-mark{width:46px;height:46px;border-radius:12px;background:#F3EEE4;border:1px solid rgba(10,42,30,.08);display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
  .tl-pm-mark svg{width:27px;height:27px;}
  .tl-pm-title{font-size:21px;font-weight:700;letter-spacing:-.01em;color:var(--ink);}
  .tl-pm-sub{font-size:13.5px;color:var(--muted);line-height:1.4;margin-top:3px;}
  .tl-pm-feats{margin:18px 0 4px;}
  .tl-pm-feat{display:flex;gap:11px;align-items:flex-start;padding:10px 0;border-bottom:1px solid var(--hair);}
  .tl-pm-feat:last-child{border-bottom:none;}
  .tl-pm-check{width:22px;height:22px;border-radius:50%;background:var(--accent);display:flex;align-items:center;justify-content:center;flex:0 0 auto;margin-top:1px;color:var(--paper);}
  .tl-pm-ft{font-size:15px;font-weight:600;color:var(--ink);}
  .tl-pm-fd{font-size:13px;color:var(--muted);line-height:1.4;margin-top:1px;}
  .tl-pm-price{text-align:center;font-size:13px;color:var(--muted);margin:16px 0 12px;}
  .tl-pm-later{margin-top:8px;width:100%;height:46px;border-radius:14px;border:none;background:transparent;color:var(--muted);font-weight:600;font-size:14.5px;cursor:pointer;font-family:inherit;}
  .tl-pm-foot{text-align:center;font-size:12px;color:var(--muted);margin-top:6px;line-height:1.4;}
  .tl-pm-restore{margin-top:2px;width:100%;height:40px;border-radius:12px;border:none;background:transparent;color:var(--accent);font-weight:600;font-size:13.5px;cursor:pointer;font-family:inherit;}
  .tl-pm-legal{margin-top:14px;font-size:11px;line-height:1.5;color:var(--muted);text-align:center;}
  .tl-pm-lgl-a{color:var(--accent);text-decoration:underline;cursor:pointer;}
  .tl-card.tl-pmcard{background:linear-gradient(135deg,var(--accent),var(--deepfam));border-radius:16px;padding:16px;color:#fff;border:none;}
  .tl-pmcard .h{display:flex;align-items:center;gap:10px;}
  .tl-pmcard .h .m{width:34px;height:34px;border-radius:9px;background:#F3EEE4;border:1px solid rgba(10,42,30,.10);display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
  .tl-pmcard .h .m svg{width:20px;height:20px;}
  .tl-pmcard .t{font-size:17px;font-weight:700;letter-spacing:-.01em;}
  .tl-pmcard .s{font-size:13px;opacity:.92;margin:9px 0 14px;line-height:1.45;}
  .tl-pmcard .up{width:100%;height:44px;border-radius:11px;border:none;background:#fff;color:var(--accent);font-weight:700;font-size:14.5px;cursor:pointer;font-family:inherit;}
  .tl-card.tl-pmcard.active{background:none;border:1px solid var(--hair);color:var(--ink);}
  .tl-pmcard.active .m{background:#F3EEE4;}
  .tl-pmcard.active .t{color:var(--ink);}
  .tl-pmopt{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:13px 2px;width:100%;background:none;border:none;text-align:left;font-family:inherit;cursor:pointer;}
  .tl-pmopt+.tl-pmopt{border-top:1px solid var(--hair);}
  .tl-pmopt .ol{font-size:15px;font-weight:600;color:var(--ink);}
  .tl-pmopt .od{font-size:12.5px;color:var(--muted);margin-top:2px;line-height:1.35;}
  /* THE SHEET MUST NOT GROW UNDER A FINGER. Two of the three rows change when the survey
     lands — C from "Counting what will be removed." to the real sentence, B from the local
     figure to the deduplicated one — and the settled sentence is the longer of the two, so
     the sheet reflowed and shifted the buttons mid-tap. Seen on a device twice.
     The row is a one-cell grid holding the visible text and an invisible sizer stacked on
     top of each other, so the box is the height of the TALLER. The sizer is the same sentence
     built with ZONE_RESERVE's counts, so the reservation is measured rather than guessed and
     tracks the font, the width and Dynamic Type for free.
     It lives in an ATTRIBUTE and is drawn by ::before: no text node, so it cannot be selected,
     read out, or counted as another line of copy on the sheet. */
  .tl-pmopt .od[data-sizer]{display:grid;}
  .tl-pmopt .od[data-sizer]>span{grid-area:1/1;}
  .tl-pmopt .od[data-sizer]::before{content:attr(data-sizer);grid-area:1/1;visibility:hidden;pointer-events:none;}
  .tl-pmlock{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600;color:var(--accent);flex:0 0 auto;}
  .tl-pmon{flex:0 0 auto;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--accent);background:rgba(14,124,102,.1);padding:3px 9px;border-radius:20px;}
  .tl-lockcard{background:var(--chipbg);border:1px solid var(--hair);border-radius:14px;padding:14px;margin:6px 0 14px;}
  .tl-lockcard-h{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:700;color:var(--ink);}
  .tl-lockcard-h svg{color:var(--accent);}
  .tl-lockcard-s{font-size:13px;color:var(--muted);line-height:1.45;margin:7px 0 12px;}
  .tl-lockcard-btns{display:flex;gap:8px;}
  .tl-lockbtn{flex:1;height:42px;border-radius:11px;border:none;background:var(--accent);color:var(--paper);font-weight:600;font-size:14px;font-family:inherit;cursor:pointer;}
  .tl-lockbtn.sec{background:transparent;border:1px solid var(--hair);color:var(--ink);}
  .tl-tile.locked{opacity:.74;}
  .tl-tile.locked .tl-tilebg{filter:grayscale(.45);}
  /* 6A edit mode */
  @keyframes tljiggle{0%{transform:scale(1)}50%{transform:scale(.972)}100%{transform:scale(1)}}
  .tl-tile.jiggle,.tl-hero.jiggle,.tl-rowgroup.jiggle{animation:tljiggle 1.5s ease-in-out infinite;}
  .tl-tile.jiggle:nth-child(2n){animation-duration:1.7s;}
  .tl-tile.jiggle:nth-child(3n){animation-duration:1.35s;}
  .tl-rowgroup.jiggle:nth-child(2n){animation-duration:1.7s;}
  .tl-tile.jiggle:active{transform:none;}
  .tl-home.reordering .tl-tile.jiggle,.tl-home.reordering .tl-hero.jiggle,.tl-home.reordering .tl-rowgroup.jiggle{animation:none;}
  .tl-editbadge{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 1px 4px rgba(0,0,0,.28);flex:0 0 auto;}
  .tl-tile .tl-editbadge,.tl-hero .tl-editbadge{position:absolute;top:-6px;left:-6px;width:22px;height:22px;z-index:8;}
  .tl-editbadge.sm{width:22px;height:22px;margin:0 2px 0 1px;}
  .tl-editbadge.del{background:#E5484D;cursor:pointer;}
  .tl-editbadge.del::before{content:"";width:12px;height:2.4px;border-radius:2px;background:#fff;}
  .tl-editbadge.lock{background:#9AA0A8;}
  .tl-donebtn{border:none;background:var(--accent);color:var(--paper);font-family:inherit;font-weight:600;font-size:14px;border-radius:11px;padding:7px 15px;cursor:pointer;-webkit-tap-highlight-color:transparent;}
  .tl-donebtn:active{opacity:.8;}
  .tl-confirm{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:60;width:min(340px,86vw);background:var(--surface);border-radius:20px;padding:22px 20px 16px;box-shadow:0 24px 60px rgba(0,0,0,.35);}
  .tl-confirm.anim{animation:confIn .2s cubic-bezier(.2,.8,.2,1);}
  @keyframes confIn{from{opacity:0;transform:translate(-50%,-46%) scale(.96)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}
  .tl-confirm-h{font-size:18px;font-weight:700;letter-spacing:-.01em;color:var(--ink);text-align:center;}
  .tl-confirm-sub{font-size:13.5px;color:var(--t2);text-align:center;margin-top:7px;line-height:1.4;}
  .tl-confirm-btns{display:flex;gap:10px;margin-top:18px;}
  .tl-confirm-btns button{flex:1;border:none;border-radius:12px;padding:12px 0;font-family:inherit;font-weight:600;font-size:15px;cursor:pointer;-webkit-tap-highlight-color:transparent;}
  .tl-confirm-cancel{background:var(--chipbg);color:var(--ink);}
  .tl-confirm-del{background:#E5484D;color:#fff;}
  .tl-confirm-btns button:active{opacity:.8;}
  .tl-lockchip{position:absolute;top:10px;right:10px;width:24px;height:24px;border-radius:50%;background:rgba(10,42,30,.16);display:flex;align-items:center;justify-content:center;color:var(--ink);z-index:2;}
  .tl-lockchip svg{width:12px;height:12px;}
  /* QUICK VIEW. A read-only card over everything, centred, inert: pointer-events:none, no data-act. */
  .tl-peek-scrim{position:fixed;inset:0;background:rgba(20,24,27,.18);z-index:55;pointer-events:none;animation:fade .12s ease;}
  .peeking{position:relative;z-index:56;transform:scale(1.03);box-shadow:0 10px 26px rgba(0,0,0,.18);transition:transform .12s ease;}
  .tl-peek{position:fixed;max-height:70vh;overflow:hidden;z-index:60;background:var(--surface);border:1px solid var(--hair);border-radius:18px;box-shadow:0 24px 60px rgba(0,0,0,.28);padding:12px 14px 14px;pointer-events:none;animation:fade .12s ease;}
  .tl-peek-h{display:flex;align-items:center;gap:10px;margin-bottom:8px;}
  .tl-peek-glyph{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
  .tl-peek-name{font-size:16px;font-weight:700;color:var(--ink);flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .tl-peek-meta{font-size:12.5px;color:var(--muted);flex:0 0 auto;}
  .tl-peek-row{display:flex;align-items:center;gap:10px;padding:7px 2px;border-top:1px solid var(--hair);}
  .tl-peek-circ{width:16px;height:16px;border-radius:50%;border:1.6px solid var(--circ);flex:0 0 auto;}
  .tl-peek-text{font-size:14.5px;color:var(--ink);flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .tl-peek-empty{font-size:14px;color:var(--muted);padding:10px 2px 4px;}
  .tl-peek-more{font-size:12.5px;color:var(--muted);padding:8px 2px 0;border-top:1px solid var(--hair);}
  .tl-peek-kv{display:flex;flex-direction:column;gap:2px;padding:7px 2px;border-top:1px solid var(--hair);font-size:14px;color:var(--ink);}
  .tl-peek-k{font-size:11.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);}
  .tl-peek-notes{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;white-space:pre-line;line-height:1.4;}
  .tl-peek-circ.on{background:var(--accent);border-color:var(--accent);color:var(--paper);display:flex;align-items:center;justify-content:center;}   /* the check is the mark on the fill (test/markcontrast) */
  .tl-peek-text.done{text-decoration:line-through;color:var(--muted);}
  .tl-lockchip.sm{position:static;width:22px;height:22px;background:rgba(10,42,30,.12);flex:0 0 auto;}
  .tl-rowgroup.locked .tl-row2-b{opacity:.84;}
  .tl-list-locked [data-handle]{display:none!important;}
  .tl-list-locked .tl-check{pointer-events:none;opacity:.5;}

  .tl-empty{padding:54px 10px;text-align:center;color:var(--muted);font-size:15px;line-height:1.5;}
  .tl-addbar{z-index:40;box-sizing:border-box;display:flex;gap:8px;padding:12px 0 10px;
    background:linear-gradient(to top, var(--paper) 64%, rgba(241,243,241,0));}
  .tl-list-pad{padding-bottom:28px;scroll-padding-bottom:28px;}
  .tl-addin{flex:1;box-sizing:border-box;-webkit-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent;background-clip:padding-box;height:48px;border-radius:14px;border:1px solid var(--accent);background:var(--surface);padding:0 16px;font-size:16px;color:var(--ink);outline:none;box-shadow:none;font-family:inherit;}
  .tl-addin:focus,.tl-addin:focus-visible{outline:none !important;box-shadow:none;border-color:var(--accent);}
  .tl-addin.flash{animation:tlAddFlash .85s ease-out;}
  .tl-addbtn{height:48px;width:48px;flex:0 0 auto;border-radius:14px;border:none;background:var(--accent);color:var(--paper);display:flex;align-items:center;justify-content:center;cursor:pointer;}
  .tl-addbtn:disabled{opacity:.4;cursor:default;}

  /* ---- calendars ---------------------------------------------------------
     An event row borrows the task row's geometry so the controls are learned once, and
     differs only where it must: a hollow mark rather than a progress circle, and a chip
     that reads as a time rather than a deadline. */
  .tl-evrow .tl-sres-sub{display:flex;align-items:center;gap:5px;}
  .tl-evrow.dismissed{opacity:.5;}
  /* THE BELL IS THE TICK'S SHAPE — a 26px circle, hollow off, accent-filled on — so the row's two
     controls read as one family, and so the on state is a mark on an accent fill and takes
     color:var(--paper) under the same rule as every other. test/markcontrast discovers this rule
     by its background and measures it; nothing here is exempt. */
  .tl-evbell{flex:0 0 auto;width:26px;height:26px;border-radius:50%;border:1.5px solid var(--hair2);background:transparent;color:var(--muted);display:flex;align-items:center;justify-content:center;padding:0;cursor:pointer;font:inherit;}
  .tl-evbell.on{background:var(--accent);border-color:var(--accent);color:var(--paper);}
  .tl-chip.ev{background:var(--chipbg);color:var(--t2);}
  .tl-agcut{font-size:12.5px;color:var(--muted);padding:14px 2px 4px;text-align:center;}
  .tl-evhead{display:flex;align-items:center;gap:10px;}
  .tl-evglyph{flex:0 0 auto;color:var(--accent);display:flex;}
  .tl-evtitle{font-size:19px;font-weight:700;letter-spacing:-.01em;color:var(--ink);min-width:0;}
  .tl-evtext{font-size:15px;color:var(--ink);white-space:pre-wrap;word-break:break-word;}
  .tl-calhead{display:flex;align-items:center;gap:8px;}
  .tl-caltick{flex:0 0 auto;border:none;background:none;padding:0;cursor:pointer;font:inherit;color:inherit;display:flex;align-items:center;}
  /* margin-left:auto RIGHT-ALIGNS IT, like every other chevron in this card. Without it the
     chevron sits immediately after the name, so a column of calendars with names of different
     lengths had its chevrons at different x — the one thing a column of disclosures must not do. */
  .tl-calchev{flex:0 0 auto;margin-left:auto;color:var(--muted);display:flex;transition:transform .18s ease;}
  .tl-calpick.open .tl-calchev{transform:rotate(180deg);}
  .tl-calrow{padding:10px 0;border-top:1px solid var(--hair);}
  .tl-calrow:first-of-type{border-top:none;padding-top:2px;}
  .tl-calpick{display:flex;align-items:center;gap:11px;width:100%;background:none;border:none;padding:0;cursor:pointer;font-family:inherit;text-align:left;}
  .tl-calmark{width:22px;height:22px;border-radius:7px;border:1.5px solid var(--hair2);display:flex;align-items:center;justify-content:center;flex:0 0 auto;color:var(--paper);}
  /* .tl-caltick, NOT .tl-calpick. This rule could never match: `on` is written onto the TICK,
     and .tl-calmark is the tick's child — a sibling's child from .tl-calpick's point of view, so
     neither half of the old selector held. The tick therefore never took its accent fill and the
     check, which is #fff, sat on --surface: #FFFFFF in light at ratio 1.00 and #202428 in dark at
     15.4. Invisible in one appearance, correct in the other, and every existing test passed.
     WHY THE APPEARANCE SPLIT WAS THE CLUE, worth keeping: applyTheme only swaps token VALUES —
     paper, ink, surface, accent. It changes no layout, no position, no z-index, no
     pointer-events. So a light/dark difference in this app can only ever be colour, never
     layout, and "something is sitting over the row" was ruled out before it was investigated. */
  .tl-caltick.on .tl-calmark{background:var(--accent);border-color:var(--accent);}
  .tl-calmain{min-width:0;display:flex;flex-direction:column;}
  .tl-calname{font-size:15px;font-weight:600;color:var(--ink);}
  .tl-calacct{font-size:12.5px;color:var(--muted);}
  .tl-calglyphs{display:grid;grid-template-columns:repeat(auto-fill,30px);gap:6px;justify-content:space-between;margin:9px 0 2px 33px;}
  .tl-calglyph{width:30px;height:30px;border-radius:9px;border:1.5px solid transparent;background:var(--paper);color:var(--t2);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;}
  .tl-calglyph.sel{border-color:var(--ink);color:var(--ink);}
  .tl-sec{margin-top:22px;}
  .tl-sec h2{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);margin:0 0 10px;padding-left:2px;}
  .tl-card{background:var(--surface);border:1px solid var(--hair);border-radius:16px;padding:16px;}
  .tl-note{font-size:13px;color:var(--muted);margin:0 0 12px;line-height:1.45;}
  .tl-themes{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
  .tl-theme{display:flex;align-items:center;gap:10px;padding:12px;border-radius:14px;border:1.5px solid var(--hair);background:var(--surface);cursor:pointer;font-family:inherit;font-size:14px;font-weight:600;color:var(--ink);text-align:left;}
  .tl-theme.sel{border-color:var(--accent);}
  .tl-swpair{display:flex;flex:0 0 auto;}
  .tl-swpair i{width:20px;height:20px;border-radius:50%;display:block;border:2px solid var(--surface);}
  .tl-swpair i+i{margin-left:-9px;}
  .tl-input{width:100%;height:48px;border:1px solid var(--hair);border-radius:14px;padding:0 14px;font-size:15px;font-family:inherit;color:var(--ink);background:var(--paper);outline:none;}
  .tl-input:focus{border-color:var(--accent);}
  .tl-btn{width:100%;height:48px;border-radius:14px;border:none;background:var(--accent);color:var(--paper);font-weight:700;font-size:15px;cursor:pointer;font-family:inherit;margin-top:10px;}
  .tl-btn.sec{background:var(--surface);border:1px solid var(--hair);color:var(--ink);}
  .tl-btn:disabled{opacity:.4;cursor:default;}
  .tl-acct{display:flex;align-items:center;gap:11px;}
  .tl-dot{width:9px;height:9px;border-radius:50%;background:var(--accent);flex:0 0 auto;}
  .tl-acct .em{font-weight:600;font-size:15px;} .tl-acct .st{font-size:13px;color:var(--muted);margin-top:1px;}
  .tl-rowline{display:flex;justify-content:space-between;align-items:center;padding:11px 0;border-bottom:1px solid var(--hair);font-size:14px;}
  .tl-rowline:last-of-type{border-bottom:none;}
  .tl-rowline .k{color:var(--muted);} .tl-rowline .v{font-weight:600;}

  .tl-scrim{position:fixed;inset:0;background:rgba(20,24,27,.34);z-index:40;}
  .tl-scrim.anim{animation:fade .2s ease;}
  .tl-sheet{position:fixed;left:0;right:0;bottom:0;z-index:41;background:var(--surface);border-radius:22px 22px 0 0;
    padding:8px 18px calc(22px + env(safe-area-inset-bottom));max-width:468px;margin:0 auto;max-height:90vh;overflow:auto;box-shadow:0 -8px 40px rgba(0,0,0,.16);}
  .tl-sheet.anim{animation:sheetUp .28s cubic-bezier(.2,.8,.2,1);}
  /* Option 3: keyboard choreography. --kb is the live keyboard height (0 when hidden).
     With resize:'none' the viewport no longer shrinks, so anything sized against vh or
     safe-area-inset-bottom is stale while the keyboard is up — both are corrected here.
     --kbover tucks sheets slightly behind the keyboard so its rounded corners don't
     show the page through them. */
  :root{--kbover:28px;}
  .tl-sheet{bottom:var(--kb,0px);transition:bottom var(--kbms,250ms) cubic-bezier(.17,.59,.4,.77),
            max-height var(--kbms,250ms) cubic-bezier(.17,.59,.4,.77);}
  #app{transition:padding-bottom var(--kbms,250ms) cubic-bezier(.17,.59,.4,.77);}
  body.kb-up .tl-sheet{
    bottom:calc(var(--kb,0px) - var(--kbover));
    padding-bottom:calc(18px + var(--kbover));            /* was 22px + safe-area (dead space) */
    /* leave the grip clear of the Dynamic Island / notch so it stays draggable */
    max-height:calc(100vh - var(--kb,0px) + var(--kbover) - env(safe-area-inset-top) - 24px);
  }
  body.kb-up #app{padding-bottom:calc(var(--kb,0px) + 2px);}  /* +2 so the gap below the add bar matches the 12px above it */

  .tl-sheet-create{overflow:auto;-webkit-overflow-scrolling:touch;}
  .tl-grip{width:38px;height:5px;border-radius:99px;background:var(--hair2);margin:8px auto 14px;}
  .tl-griparea{touch-action:none;cursor:grab;display:flex;align-items:center;justify-content:center;height:32px;margin:-2px 0 8px;}
  .tl-griparea:active{cursor:grabbing;}
  .tl-griparea .tl-grip{margin:0;}
  .tl-sheet-h{font-size:21px;font-weight:700;letter-spacing:-.01em;padding-bottom:2px;}
  .tl-stitle{font-size:21px;font-weight:700;letter-spacing:-.01em;width:100%;border:none;outline:none;background:transparent;color:var(--ink);padding:2px 0 6px;font-family:inherit;}
  .tl-stitle-row{display:flex;align-items:center;gap:6px;}
  .tl-stitle-row .tl-stitle{flex:1;min-width:0;width:auto;}
  .tl-sheet-export{flex:0 0 auto;width:38px;height:38px;border-radius:50%;border:none;background:transparent;display:inline-flex;align-items:center;justify-content:center;color:var(--accent);cursor:pointer;-webkit-tap-highlight-color:transparent;}
  .tl-sheet-export:active{background:var(--chipbg);}
  .tl-field{margin-top:16px;}
  .tl-label{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);margin-bottom:8px;display:block;}
  .tl-sublabelrow{display:flex;align-items:baseline;justify-content:space-between;}
  .tl-subclear{display:inline-flex;align-items:center;gap:5px;border:none;background:transparent;color:var(--t2);font:inherit;font-size:12.5px;font-weight:600;cursor:pointer;padding:0 2px;}
  .tl-subclear svg{color:var(--red);}
  .tl-crumb{display:block;border:none;background:transparent;color:var(--t2);font:inherit;font-size:13px;font-weight:600;padding:0 2px 8px;cursor:pointer;text-align:left;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .tl-subrow{display:flex;align-items:center;gap:10px;padding:7px 2px;}
  .tl-subrow.tl-subdragging{opacity:.55;}
  .tl-subhandle{margin-left:auto;color:var(--muted);padding:4px 2px;cursor:grab;touch-action:none;flex:0 0 auto;display:inline-flex;}
  .tl-subcirc{width:20px;height:20px;border-radius:50%;border:1.6px solid var(--circ);background:transparent;flex:0 0 auto;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--paper);padding:0;}
  .tl-subcirc.on{background:var(--accent);border-color:var(--accent);}
  .tl-subtext{font-size:15px;color:var(--ink);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border:none;background:transparent;font-family:inherit;padding:0;text-align:left;cursor:pointer;flex:1;}
  .tl-subtext.done{text-decoration:line-through;opacity:.45;}
  .tl-subadd{display:flex;gap:8px;margin-top:6px;}
  .tl-subadd input{flex:1;min-width:0;border:1px solid var(--hair2);background:var(--surface);color:var(--ink);border-radius:12px;padding:10px 12px;font:inherit;font-size:14.5px;outline:none;}
  .tl-subadd input::placeholder{color:var(--muted);}
  .tl-subaddbtn{width:38px;align-self:stretch;border-radius:12px;border:none;background:var(--accent);color:var(--paper);cursor:pointer;flex:0 0 auto;display:flex;align-items:center;justify-content:center;}
  .tl-subaddbtn:disabled{opacity:.4;cursor:default;}
  .tl-notes{width:100%;min-height:90px;border:1px solid var(--hair);border-radius:14px;padding:12px 14px;font-size:15px;line-height:1.45;font-family:inherit;color:var(--ink);background:var(--paper);outline:none;resize:vertical;}
  .tl-notes:focus,.tl-due:focus,.tl-timein:focus{border-color:var(--accent);}
  .tl-duewrap{display:flex;gap:8px;align-items:center;}
  .tl-due{flex:1;height:48px;border:1px solid var(--hair);border-radius:14px;padding:0 14px;font-size:15px;font-family:inherit;color:var(--ink);background:var(--paper);outline:none;}
  .tl-clear{height:48px;padding:0 14px;border-radius:14px;border:1px solid var(--hair);background:var(--surface);color:var(--muted);font-weight:600;font-size:13px;cursor:pointer;font-family:inherit;flex:0 0 auto;}
  .tl-setbtn{height:48px;width:52px;flex:0 0 auto;border-radius:14px;border:none;background:var(--accent);color:var(--paper);display:flex;align-items:center;justify-content:center;cursor:pointer;}
  .tl-duenow{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:10px;font-size:14px;color:var(--ink);font-weight:600;}
  .tl-link{border:none;background:none;color:var(--red);font-weight:700;font-size:13px;cursor:pointer;font-family:inherit;padding:0;}
  .tl-duehint{font-size:12.5px;color:var(--muted);margin-top:8px;line-height:1.4;}
  .tl-duebtns{display:flex;gap:16px;}
  .tl-cal{border:1px solid var(--hair);border-radius:16px;padding:14px;}
  .tl-cal-h{display:flex;align-items:center;justify-content:space-between;font-weight:700;font-size:15px;color:var(--ink);margin-bottom:10px;}
  .tl-cal-nav{width:38px;height:38px;border-radius:10px;border:none;background:var(--paper);color:var(--ink);font-size:20px;cursor:pointer;font-family:inherit;}
  .tl-cal-w{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px;}
  .tl-cal-w span{text-align:center;font-size:11px;font-weight:700;color:var(--muted);}
  .tl-cal-g{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;}
  .tl-cal-d{aspect-ratio:1;border:none;background:none;border-radius:9px;font-size:14px;color:var(--ink);cursor:pointer;font-family:inherit;}
  .tl-cal-d:active{background:var(--paper);}
  .tl-cal-d.sel{background:var(--accent);color:var(--paper);font-weight:700;}
  .tl-cal-d.today:not(.sel){box-shadow:inset 0 0 0 2px var(--ink);font-weight:700;}
  .tl-cal-e{aspect-ratio:1;}
  .tl-cal-t{display:flex;align-items:center;gap:8px;margin-top:14px;flex-wrap:wrap;}
  .tl-sel{height:42px;border:1px solid var(--hair);border-radius:10px;background:var(--paper);color:var(--ink);font-size:15px;font-family:inherit;padding:0 8px;}
  .tl-ampm{height:42px;padding:0 14px;border:1px solid var(--hair);border-radius:10px;background:var(--surface);color:var(--ink);font-weight:600;font-size:13px;cursor:pointer;font-family:inherit;}
  .tl-ampm.sel{background:var(--accent);border-color:var(--accent);color:var(--paper);}
  .tl-cal-btns{display:flex;gap:8px;margin-top:14px;}
  .tl-cal-btns .tl-btn{margin-top:0;flex:1;width:auto;}
  .tl-chips{display:flex;flex-wrap:wrap;gap:8px;}
  .tl-chipbtn{display:inline-flex;align-items:center;gap:6px;padding:9px 13px;border-radius:11px;border:1px solid var(--hair);background:var(--surface);color:var(--ink);font-size:13px;font-weight:600;cursor:pointer;font-family:inherit;}
  .tl-chipbtn.sel{background:var(--accent);border-color:var(--accent);color:var(--paper);}
  .tl-days{display:flex;gap:6px;margin-top:10px;}
  .tl-endrow{margin-top:12px;}
  .tl-enddate{width:100%;box-sizing:border-box;border:1px solid var(--hair2);background:var(--surface);color:var(--ink);border-radius:12px;padding:11px 14px;font:inherit;font-size:15px;outline:none;-webkit-appearance:none;appearance:none;}
  .tl-endcount{display:flex;align-items:center;gap:16px;}
  .tl-stepb{width:40px;height:40px;border-radius:12px;border:1px solid var(--hair);background:var(--surface);color:var(--ink);font-size:22px;line-height:1;cursor:pointer;font-family:inherit;display:flex;align-items:center;justify-content:center;-webkit-tap-highlight-color:transparent;}
  .tl-stepb:active{background:var(--chipbg);}
  .tl-endn{font-size:15px;font-weight:600;color:var(--ink);min-width:70px;text-align:center;}
  .tl-movehead{display:inline-flex;align-items:center;gap:6px;border:none;background:none;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent;}
  .tl-bchev{color:var(--t2);transition:transform .2s;display:flex;flex:0 0 auto;}
  .tl-movehead.open .tl-bchev{transform:rotate(180deg);}
  .tl-dayb{flex:1;height:40px;border:1px solid var(--hair);border-radius:10px;background:var(--surface);color:var(--ink);font-weight:700;font-size:13px;cursor:pointer;font-family:inherit;padding:0;}
  .tl-dayb.sel{background:var(--accent);border-color:var(--accent);color:var(--paper);}
  .tl-timein{margin-top:10px;width:100%;height:46px;border:1px solid var(--hair);border-radius:12px;padding:0 12px;font-size:15px;font-family:inherit;color:var(--ink);background:var(--paper);outline:none;}
  .tl-donebtn{margin-top:22px;width:100%;height:50px;border-radius:14px;border:none;background:var(--accent);color:var(--paper);font-weight:700;font-size:15px;cursor:pointer;font-family:inherit;}
  .tl-topicons .tl-donebtn{margin-top:0;width:auto;height:38px;border-radius:19px;padding:0 16px;font-size:14px;font-weight:600;color:var(--paper);}
  .tl-donebtn:disabled{opacity:.4;cursor:default;}
  .tl-delbtn{margin-top:10px;width:100%;height:48px;border-radius:14px;border:1px solid #EBD3D3;background:#FBF1F1;color:var(--red);font-weight:700;font-size:14px;cursor:pointer;font-family:inherit;}

  .tl-preview{display:flex;align-items:center;gap:12px;margin:8px 0 2px;}
  .tl-pvtile{width:62px;height:62px;border-radius:18px;display:flex;align-items:center;justify-content:center;font-size:26px;flex:0 0 auto;color:#1c2422;}
  .tl-pvname{font-size:18px;font-weight:700;color:var(--ink);} .tl-pvname.ph{color:var(--muted);}
  .tl-emojis{display:grid;grid-template-columns:repeat(8,1fr);gap:6px;}
  .tl-emoji-btn{aspect-ratio:1;border-radius:12px;border:1.5px solid transparent;background:var(--paper);font-size:20px;cursor:pointer;display:flex;align-items:center;justify-content:center;}
  .tl-emoji-btn.sel{border-color:var(--accent);background:var(--surface);}
  .tl-colors{display:flex;flex-wrap:wrap;gap:12px;}
  .tl-color-btn{width:34px;height:34px;border-radius:50%;border:none;cursor:pointer;}
  .tl-color-btn.sel{outline:2.5px solid var(--ink);outline-offset:2px;}
  @media(max-width:380px){.tl-emojis{grid-template-columns:repeat(6,1fr);}}
  .tl-calcustom{display:flex;align-items:center;gap:10px;}
  .tl-calsuffix{font-size:13px;color:var(--muted);font-weight:600;flex:0 0 auto;padding-top:10px;}
  .tl-calurl-add{display:flex;gap:8px;align-items:center;}
  .tl-calurl-in{flex:1;min-width:0;}
  .tl-calurl-btn{flex:0 0 auto;height:48px;padding:0 18px;border-radius:12px;border:none;background:var(--ink);color:var(--paper);font:inherit;font-weight:600;font-size:14px;cursor:pointer;}
  .tl-calurl-list{margin-top:10px;display:flex;flex-direction:column;gap:6px;}
  .tl-calurl-row{display:flex;align-items:center;gap:8px;background:var(--paper);border:1px solid var(--hair);border-radius:10px;padding:8px 6px 8px 12px;}
  .tl-calurl-text{flex:1;min-width:0;font-size:13px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .tl-calurl-x{flex:0 0 auto;width:28px;height:28px;border-radius:8px;border:none;background:transparent;color:var(--muted);display:flex;align-items:center;justify-content:center;cursor:pointer;}
  .tl-calurl-x:hover{color:var(--red);}
  .tl-toggle{display:flex;align-items:center;justify-content:space-between;gap:14px;}
  .tl-toggle .lbl{font-size:15px;font-weight:600;color:var(--ink);}
  .tl-toggle .sub{font-size:12.5px;color:var(--muted);margin-top:2px;line-height:1.35;}
  /* OFF IS A MID-GREY, not a hairline. --hair2 sat at 1.49 against the card, so an off
     switch barely read as a control at all — which is what made on and off hard to tell apart
     in Mono, where there is no hue doing the work instead. --muted measures 4.51 against the
     card and 4.20 against the knob, and still separates from the ON track in mono at 3.68
     light / 2.82 dark. --t2 was tried and rejected: heavier at 5.97, so it reads as a FILLED
     control when off, and its mono on/off separation is worse at 2.13. */
  .tl-switch{width:48px;height:30px;border-radius:99px;background:var(--muted);position:relative;border:none;cursor:pointer;flex:0 0 auto;transition:background .2s;}
  .tl-switch.on{background:var(--accent);}
  /* THE KNOB IS --paper, NOT #fff, and this is the thirteenth instance of that bug. The ON
     track is var(--accent), which in dark Mono is #E7E8E9 — a white knob on it measured 1.23
     and simply vanished. --paper flips with the mode, so it contrasts with the accent in both:
     worst case across six themes and both modes is 4.70. */
  .tl-switch i{position:absolute;top:3px;left:3px;width:24px;height:24px;border-radius:50%;background:var(--paper);transition:left .2s;box-shadow:0 1px 2px rgba(0,0,0,.25);}
  .tl-switch.on i{left:21px;}

  button:focus-visible,input:focus-visible,textarea:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
  @keyframes slideIn{from{opacity:0;transform:translateX(10px)}to{opacity:1;transform:none}}
  @keyframes tlFade{from{opacity:0}to{opacity:1}}
  @keyframes tlAddFlash{0%{box-shadow:0 0 0 4px color-mix(in srgb, var(--accent) 45%, transparent);}100%{box-shadow:0 0 0 4px transparent;}}
  @keyframes taskFlash{0%{box-shadow:inset 0 0 0 3px color-mix(in srgb, var(--accent) 65%, transparent);}62%{box-shadow:inset 0 0 0 3px color-mix(in srgb, var(--accent) 65%, transparent);}100%{box-shadow:inset 0 0 0 3px transparent;}}
  @keyframes fadeUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
  @keyframes fade{from{opacity:0}to{opacity:1}}
  @keyframes sheetUp{from{transform:translateY(100%)}to{transform:none}}
  @keyframes pop{0%{transform:scale(1)}45%{transform:scale(1.35)}100%{transform:scale(1)}}
  @media (prefers-reduced-motion: reduce){.tl-root *{animation:none!important;transition:none!important;}}
  @media (min-width:1000px){
    /* THREE PANELS UNDER A BAR. Widths are the iPad mini's (293 / 440 / 400 = 1133); a wider iPad gives panel 2 the room. */
    .tl-wrap-panels{max-width:none;padding:0;height:100%;}
    .tl-panels{display:grid;grid-template-columns:293px minmax(440px,1fr) 400px;grid-template-rows:auto minmax(0,1fr);height:100%;}
    .tl-topbar{grid-column:1 / -1;display:flex;align-items:center;gap:10px;padding:14px 14px 14px 16px;border-bottom:1px solid var(--hair);background:var(--paper);}
    .tl-topbar-main,.tl-topbar .tl-head,.tl-topbar .tl-headrow{display:contents;}
    .tl-topbar .tl-logomark{order:0;margin-left:0;}
    .tl-topbar .tl-headdate{order:1;flex:0 0 auto;text-align:left;padding:0 10px 0 14px;}
    .tl-topbar-quick{order:2;flex:1;min-width:0;}
    .tl-topbar-quick .tl-quick{margin:0;}
    .tl-topbar .tl-topicons{order:3;}
    .tl-topbar .tl-donebtn{order:3;margin:0;width:auto;height:38px;padding:0 14px;}
    .tl-topbar-p3{order:4;flex:0 0 372px;display:flex;justify-content:flex-end;align-items:center;gap:4px;min-height:38px;border-left:1px solid var(--hair);padding-left:12px;}
    .tl-p1,.tl-p2,.tl-p3{min-width:0;min-height:0;overflow:auto;padding:14px 12px 0;box-sizing:border-box;border-right:1px solid var(--hair);}
    .tl-p3{border-right:none;padding:8px 18px 0;}
    .tl-p1 .tl-home{min-height:0;}
    .tl-p2 .tl-bview-tasks{height:auto;min-height:100%;}
    .tl-detail{padding:0 0 18px;}
    .tl-mark{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;opacity:.85;}
    .tl-mark-logo{width:64px;height:auto;color:#2E6B52;}
    .tl-marksub{color:var(--muted);font-size:14px;}
  }
  @media (min-width:600px) and (max-width:999px){
    /* TWO PANELS UNDER THE BAR, the detail as a band sheet. The bar and panel rules the two wide modes
       share are repeated from the 1000px block above rather than hoisted: that block is pinned
       verbatim by test/golden, and a media block may only be ADDED. */
    .tl-wrap-panels{max-width:none;padding:0;height:100%;}
    .tl-panels.tl-two{display:grid;grid-template-columns:293px minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);height:100%;}
    .tl-panels.tl-two-wide{grid-template-columns:minmax(0,1fr);}
    .tl-topbar{grid-column:1 / -1;display:flex;align-items:center;gap:10px;padding:14px 14px 14px 16px;border-bottom:1px solid var(--hair);background:var(--paper);}
    .tl-topbar-left{display:flex;align-items:center;flex:0 0 auto;min-width:0;}
    .tl-topbar-left .tl-logomark{margin-left:0;}
    .tl-topbar-left .tl-headdate{flex:0 0 auto;text-align:left;padding:0 10px 0 14px;}
    .tl-topbar-mid{display:flex;align-items:center;gap:10px;flex:1;min-width:0;}
    .tl-topbar-mid .tl-quick{flex:1;min-width:0;max-width:560px;margin:0 auto;}   /* auto margins: the cell's leftover splits evenly around the field */
    .tl-topbar-mid .tl-topicons,.tl-topbar-mid .tl-donebtn{margin-left:auto;}   /* the icons land at the right edge */
    .tl-topbar .tl-donebtn{margin:0;width:auto;height:38px;padding:0 14px;}
    .tl-p1,.tl-p2{min-width:0;min-height:0;overflow:auto;padding:14px 12px 0;box-sizing:border-box;border-right:1px solid var(--hair);}
    .tl-p2{border-right:none;}
    .tl-p1 .tl-home{min-height:0;}
    .tl-p2 .tl-bview-tasks{height:auto;min-height:100%;}
    /* THE BAND: the phone's .tl-sheet across the whole width, 320 resting, 440 tall. No scrim. */
    .tl-sheet.tl-band{max-width:none;margin:0;height:320px;max-height:320px;transition:height .24s cubic-bezier(.2,.8,.2,1),max-height .24s cubic-bezier(.2,.8,.2,1);}
    .tl-sheet.tl-band.tall{height:440px;max-height:440px;}
    .tl-band .tl-delbtn{width:auto;min-width:220px;}
    /* the panels reserve the band's height while it is up, so the add bar and the last rows sit above it */
    .tl-two-banded .tl-p1,.tl-two-banded .tl-p2{padding-bottom:320px;}
    .tl-two-banded.tl-two-tall .tl-p1,.tl-two-banded.tl-two-tall .tl-p2{padding-bottom:440px;}
    /* the add-subtask row under the open task's children in panel 2 */
    .tl-subaddrow{padding:6px 0 8px 44px;}
    .tl-subaddrow .tl-subadd{margin:0;}
  }
  @media (min-width:1000px){
    /* THE BAR IS ONE FLEX ROW WITH ITS OWN WIDTHS, not a subgrid of the panels: a toolbar does not
       reflow because the content beneath it was resized, and a one-column grid (portrait week and
       month) does not stack it. Its cells no longer end exactly at the panel edges — accepted. The
       right cell is the bar's right-most item, so share and close sit over panel 3 whatever its width,
       and it has no border. */
    .tl-topbar{grid-column:1 / -1;display:flex;align-items:center;gap:10px;padding:14px 14px 14px 16px;border-bottom:1px solid var(--hair);background:var(--paper);}
    .tl-topbar-left{display:flex;align-items:center;flex:0 0 auto;min-width:0;}
    .tl-topbar-left .tl-logomark{margin-left:0;}
    .tl-topbar-left .tl-headdate{flex:0 0 auto;text-align:left;padding:0 10px 0 14px;}
    .tl-topbar-mid{display:flex;align-items:center;gap:10px;flex:1;min-width:0;}
    .tl-topbar-mid .tl-quick{flex:1;min-width:0;max-width:560px;margin:0 auto;}   /* auto margins: the cell's leftover splits evenly around the field */
    .tl-topbar-mid .tl-topicons,.tl-topbar-mid .tl-donebtn{margin-left:auto;}   /* the icons land at the right edge */
    .tl-topbar .tl-donebtn{margin:0;width:auto;height:38px;padding:0 14px;}
    .tl-topbar-p3{flex:0 0 auto;order:0;display:flex;justify-content:flex-end;align-items:center;gap:4px;min-height:38px;border-left:none;padding:0;}
    /* THE WIDE MONTH: grid left with square cells, chips and the selected day's list right, full height. */
    .tl-month-wide{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(280px,1fr);gap:20px;align-items:start;}
    .tl-month-r{position:sticky;top:0;max-height:calc(100vh - 300px);overflow:auto;}
    .tl-month-r .tl-mselist{margin-top:0;}
    .tl-month-r .tl-calchips{margin:0 0 12px;}
  }
  @media (min-width:600px){
    /* THE DIVIDERS: grid items placed in the same cell as the panel to their left, hugging its
       right edge, above it. 14pt wide for the finger; the panel's own hairline stays the visible line. */
    /* The panels are placed EXPLICITLY. Auto-placement will not put an item into a cell an explicitly
       placed item occupies, so with the dividers in (1,2) and (2,2) the sections were pushed to the
       next free cells — panel 1 into column 3, panels 2 and 3 onto a third row. Seen on the device
       only; the render tests cannot see grid placement. */
    .tl-p1{grid-column:1;grid-row:2;}
    .tl-p2{grid-column:2;grid-row:2;}
    .tl-p3{grid-column:3;grid-row:2;}
    .tl-two-wide .tl-p2{grid-column:1;}
    /* a spanning view (week, month) in three-panel mode takes panels 2 and 3 */
    .tl-panels-span .tl-p2{grid-column:2 / -1;border-right:none;}
    /* the panels reserve the band's height while it is up, in either wide mode */
    .tl-two-banded .tl-p1,.tl-two-banded .tl-p2{padding-bottom:320px;}
    .tl-two-banded.tl-two-tall .tl-p1,.tl-two-banded.tl-two-tall .tl-p2{padding-bottom:440px;}
    /* 44pt to land on (22 either side of the edge — Apple's floor; 14 was why drags did not take), a
       small pill at mid-height to aim at, and the 2pt line as drag feedback. No movement threshold. */
    .tl-divider{grid-row:2;justify-self:end;width:44px;margin-right:-22px;z-index:6;position:relative;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none;}
    .tl-divider::before{content:'';position:absolute;left:19px;top:50%;width:6px;height:36px;margin-top:-18px;border-radius:3px;background:var(--hair2);}
    .tl-divider[data-div="1"]{grid-column:1;}
    .tl-divider[data-div="2"]{grid-column:2;}
    .tl-divider::after{content:'';position:absolute;left:21px;top:0;bottom:0;width:2px;border-radius:1px;background:transparent;transition:background .15s ease;}
    .tl-divider:active::after{background:var(--t2);}   /* neutral on purpose: the accent is reserved for fills that carry a mark (test/markcontrast) */
  }
  @media (min-width:600px){
    /* the panels' reserve animates with the band when its height changes across a render (bandCarry) */
    .tl-two-banded .tl-p1,.tl-two-banded .tl-p2{transition:padding-bottom .24s cubic-bezier(.2,.8,.2,1);}
  }
  @media (min-width:600px){
    /* THE IPAD'S PINNED MONTH CAPS ITS CELLS AT 48. Square cells at 744 wide are 99pt, a
       six-week grid 616, and with the band's 320 reserve and the chip row the day list under
       it was 20pt. At 48 the cells are 99 × 48 — wider than tall, as most calendars draw them —
       the grid is 313 and the worst case leaves the list 140 (its header, a full row and a third
       of the next). Measured: 56 leaves 92 (no full row), 44 leaves 164 but today's ring and dot
       are 42 of it, 40 clips them. The phone (<600) and the landscape month (not pinned) are
       untouched. aspect-ratio:auto, because a max-height on a square-ratio cell shrinks its
       width too. */
    .tl-month-pinned .tl-mcell{aspect-ratio:auto;height:48px;}
  }
  @media (min-width:600px){
    /* THE BAND'S GEOMETRY WHEREVER THE BAND RENDERS: portrait's two panels (600–999) and the
       landscape spanning views (≥1000) alike. These rules lived only in the 600–999 block, so
       above 1000 a task opened from a spanning week or month fell through to the phone sheet's
       rules — 468 wide, centred, up to 90vh tall — while the panels reserved 320 for a band.
       Repeated here rather than moved: the 600–999 block is pinned verbatim by test/golden. */
    .tl-sheet.tl-band{max-width:none;margin:0;height:320px;max-height:320px;transition:height .24s cubic-bezier(.2,.8,.2,1),max-height .24s cubic-bezier(.2,.8,.2,1);}
    .tl-sheet.tl-band.tall{height:440px;max-height:440px;}
    .tl-band .tl-delbtn{width:auto;min-width:220px;}
    .tl-subaddrow{padding:6px 0 8px 44px;}
    .tl-subaddrow .tl-subadd{margin:0;}
    /* a bucket in panel 1 with a task drag over it (dropTargetTrack): the ring says "let go here" */
    .tl-p1 .tl-dropbucket{outline:2px solid var(--accent);outline-offset:3px;border-radius:22px;}
    .tl-p1 .tl-rowgroup.tl-dropbucket{border-radius:14px;}
  }
  @media (min-width:600px){
    /* THE WINDOW PREVIEW (wide layouts): the same language as the phone frame — paper, a hairline,
    a soft shadow — at the proportions of the window it previews. A Mac gets a window's radius
    and its traffic lights; an iPad gets a bezel, which is the only thing that distinguishes the
    two at a glance once the layout inside them is the same. */
    .tl-pvwin{position:relative;overflow:hidden;background:var(--paper);pointer-events:none;box-shadow:0 2px 10px rgba(0,0,0,.10);}
    .tl-pvwin.mac{border-radius:10px;border:1px solid var(--hair2);}
    .tl-pvwin.pad{border-radius:22px;border:5px solid var(--hair2);}
    .tl-pvscale.win{padding:0;}
    .tl-pvscale.win .tl-wrap{height:100%;}
    .tl-pvlights{position:absolute;top:7px;left:9px;display:flex;gap:5px;}
    .tl-pvlights i{width:8px;height:8px;border-radius:50%;background:#FF5F57;}
    .tl-pvlights i:nth-child(2){background:#FEBC2E;}
    .tl-pvlights i:nth-child(3){background:#28C840;}
  }
  @media (min-width:800px){
    /* TWO-COLUMN SETTINGS (full screen on a wide layout, 800 and up): the header across the top,
       then a data column and a looks column, each its own scroller — the pinned-month idea, so a
       group that expands in one column cannot push the other out of view. The wrap widens so each
       column is about the phone's column. Under 800 none of this applies and Settings is the
       phone's single column (see settingsHTML). */
    .tl-wrap.tl-wrap-cols{max-width:none;height:100%;}
    .tl-bview.tl-settings-wide{display:flex;flex-direction:column;height:100%;min-height:0;}
    .tl-settings-wide .tl-bhead{flex:0 0 auto;}
    /* two comfortable columns, never a centred island: each up to 640, the pair left-aligned in
       the page padding, so a wide window fills from the left and a narrow one shares the width */
    .tl-scols{flex:1 1 auto;min-height:0;display:grid;grid-template-columns:minmax(0,640px) minmax(0,640px);justify-content:start;gap:0 32px;}
    /* each column scrolls vertically only: a subpixel-wide child must never give it a sideways scroll */
    .tl-scol{min-height:0;overflow-y:auto;overflow-x:hidden;overscroll-behavior-x:none;-webkit-overflow-scrolling:touch;padding-bottom:28px;}
    .tl-scol > .tl-sec:first-child{margin-top:0;}
  }
  @media (min-width:900px){
    /* APPEARANCE: the two previews to the left of the controls they preview, aligned at the top */
    .tl-apcols{display:grid;grid-template-columns:auto minmax(0,560px);gap:0 32px;align-items:start;justify-content:start;}
    .tl-apcols .tl-pvwrap{margin:0;justify-content:flex-start;}
    .tl-apcols .tl-apcol-ctl > .tl-sec:first-child{margin-top:0!important;}
  }
  @media (hover:hover) and (pointer:fine){
    /* MAC DENSITY, under the Mac idiom only (.tl-mac is set by the app, never by this query
       alone — an iPad with a trackpad matches the query and gets none of this). At 1:1 the
       phone's numbers are iPhone density on a desktop: the date (14px) reads small against the
       text under it, the tile name (18px) is big for a 125pt tile in panel 1, and 46pt rows are
       finger height where Reminders and Notes sit at 28–32. */
    .tl-wrap.tl-mac{padding-top:28px;}                                  /* the strip the traffic lights sit in — the window's title bar is hidden */
    /* the bar and the page headers run their paper UP into that strip and start their content just
       under it, so the lights sit inside the app's own bar rather than above a band of nothing */
    .tl-mac .tl-topbar{margin-top:-28px;padding-top:32px;padding-bottom:10px;}
    .tl-mac .tl-head{padding-top:6px;}
    .tl-mac .tl-bhead{padding-top:6px;}
    .tl-mac .tl-headdate{font-size:15px;letter-spacing:0;}               /* 14 → 15, no negative tracking */
    .tl-mac .tl-head{padding:14px 2px 14px;}                             /* 16/18 → 14/14 */
    .tl-mac .tl-topbar-left .tl-headdate{font-size:15px;}
    .tl-mac .tl-tname{font-size:15px;}                                   /* 18 → 15 */
    .tl-mac .tl-tmeta{font-size:12px;}                                   /* 13 → 12 */
    .tl-mac .tl-emoji{font-size:18px;}                                   /* 20 → 18 */
    .tl-mac .tl-tile{padding:14px;}                                      /* 16 → 14 */
    .tl-mac .tl-row{min-height:36px;}                                    /* 46 → 36 */
    .tl-mac .tl-text{font-size:14px;}                                    /* 16 → 14 */
    .tl-mac .tl-row2{padding:8px 12px;}                                  /* 12/14 → 8/12 */
    .tl-mac .tl-sresult{padding:7px 4px;}                                /* 11 → 7 */
    .tl-mac .tl-sres-text{font-size:14px;}
    .tl-mac .tl-toggle .lbl{font-size:14px;}
    /* THE CONTEXT MENU (cmenuHTML): a fixed panel at the pointer, corrected against the rendered box by
       cmenuPlace. The submenu is fixed too, placed by cmenuPlace (right, left, or over the menu when
       neither side fits), shown on hover and when the keyboard opens it (.open). */
    .tl-mac .tl-cmenu{position:fixed;z-index:70;padding:6px;border-radius:10px;background:var(--surface);border:1px solid var(--hair);box-shadow:0 10px 30px rgba(0,0,0,.18),0 1px 3px rgba(0,0,0,.1);outline:none;}
    .tl-mac .tl-cmenu-item{position:relative;display:flex;align-items:center;gap:8px;width:100%;height:28px;padding:0 10px;border:none;border-radius:6px;background:transparent;color:var(--ink);font-family:inherit;font-size:13px;line-height:1;text-align:left;cursor:default;box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
    .tl-mac .tl-cmenu-lbl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
    .tl-mac .tl-cmenu-item.danger{color:var(--red);}
    .tl-mac .tl-cmenu-chev{display:inline-flex;transform:rotate(-90deg);opacity:.6;}
    .tl-mac .tl-cmenu-sub{display:none;position:fixed;z-index:71;width:220px;padding:6px;border-radius:10px;background:var(--surface);border:1px solid var(--hair);box-shadow:0 10px 30px rgba(0,0,0,.18),0 1px 3px rgba(0,0,0,.1);box-sizing:border-box;}
    .tl-mac .tl-cmenu-item.has-sub:hover > .tl-cmenu-sub,.tl-mac .tl-cmenu-item.has-sub.open > .tl-cmenu-sub{display:block;}
    /* HOVER. ONE TREATMENT EVERYWHERE — a chipbg tint painted as an inset shadow, so it lays
       OVER a tile's own colour instead of replacing it and follows each element's radius.
       Three things were wrong with the first pass, found by enumerating every clickable element
       in the Mac layout rather than by looking:
         · SCOPE. The rules were scoped to .tl-mac, which sits on .tl-wrap, but sheets, the scrim
           and the band render outside the wrap — so nothing in an overlay could ever match.
           The scope is now .tl-mac-app, set on #app itself (see render).
         · STRENGTH. One chipbg is 5%. On a large area that reads; on a 38pt bar icon it does
           not, because that circle's fill (247,247,247) sits only seven units from the page
           (240,241,242) and a 5% tint takes it to 235 — it crosses the page colour instead of
           separating from it, so the button appears to fade rather than light up. The token is
           applied TWICE, which composites to ~10% and lands the same circle at 223. The context
           menu and the source list take the same doubling, so there is still one language.
         · COVERAGE. Twenty-nine clickable kinds had no rule at all: the header buttons, the
           check circle, the drag handle, the collapse chevron, the subtask rows, the picker's
           navigation and AM/PM, the add and quick-add buttons, the bucket title, every button
           inside a sheet. They are listed below. */
    /* A TILE'S COLOUR IS A CHILD painted across it (.tl-tilebg, inset:0), so a tint on the tile
       lands UNDERNEATH it — which is why ordinary tiles did not light up while the hero and
       Upcoming did: those two carry their colour inline and have no such child. Both selectors
       are needed, one for each shape of tile. */
    .tl-mac-app .tl-tile:hover .tl-tilebg,.tl-mac-app .tl-tile:hover,
    .tl-mac-app .tl-hero:hover,.tl-mac-app .tl-row2:hover,.tl-mac-app .tl-rowwrap:hover .tl-row,
    .tl-mac-app .tl-sresult:hover,.tl-mac-app .tl-mcell:hover,.tl-mac-app .tl-ico:hover,.tl-mac-app .tl-topic:hover,
    .tl-mac-app .tl-btn:hover,.tl-mac-app .tl-chipbtn:hover,.tl-mac-app .tl-theme:hover,.tl-mac-app .tl-segb:hover,
    .tl-mac-app .tl-vidcard:hover,.tl-mac-app .tl-pmgrp:hover,.tl-mac-app .tl-badge-expand:hover,.tl-mac-app .tl-pvcell:hover,
    .tl-mac-app .tl-crumb:hover,.tl-mac-app .tl-subrow:hover,.tl-mac-app .tl-calpick:hover,.tl-mac-app .tl-caltick:hover,
    .tl-mac-app .tl-bkface:hover,.tl-mac-app .tl-color-btn:hover,.tl-mac-app .tl-bicon-btn:hover,.tl-mac-app .tl-cal-d:hover,
    .tl-mac-app .tl-switch:hover,.tl-mac-app .tl-toggle[data-act]:hover,.tl-mac-app .tl-pmopt:not(.tl-pmopt-st):hover,
    .tl-mac-app .tl-cmenu-item:hover,.tl-mac-app .tl-cmenu-item.sel,.tl-mac-app .tl-ssrc-item:hover,
    .tl-mac-app .tl-addbtn:hover,.tl-mac-app .tl-qbtn:hover,.tl-mac-app .tl-bexp:hover,.tl-mac-app .tl-btitle:hover,
    .tl-mac-app .tl-check:hover,.tl-mac-app .tl-handle:hover,.tl-mac-app .tl-collapse:hover,.tl-mac-app .tl-subhandle:hover,
    .tl-mac-app .tl-subcirc:hover,.tl-mac-app .tl-subtext:hover,.tl-mac-app .tl-subaddbtn:hover,
    .tl-mac-app .tl-clearcomp:hover,.tl-mac-app .tl-sheet-export:hover,.tl-mac-app .tl-delbtn:hover,
    .tl-mac-app .tl-movehead:hover,.tl-mac-app .tl-donebtn:hover,.tl-mac-app .tl-expbtn:hover,
    .tl-mac-app .tl-ampm:hover,.tl-mac-app .tl-cal-nav:hover,.tl-mac-app .tl-navb:not(.disabled):hover,
    .tl-mac-app .tl-pm-later:hover,.tl-mac-app .tl-pm-restore:hover,.tl-mac-app .up:hover,
    .tl-mac-app .tl-toast-act:hover{box-shadow:inset 0 0 0 999px var(--chipbg),inset 0 0 0 999px var(--chipbg);}
    /* the small square targets inside a row have no box of their own; the tint needs a shape */
    .tl-mac-app .tl-check:hover,.tl-mac-app .tl-handle:hover,.tl-mac-app .tl-collapse:hover,
    .tl-mac-app .tl-subhandle:hover,.tl-mac-app .tl-subcirc:hover{border-radius:9px;}
    /* A LINK IS UNDERLINED, not tinted: it is inline text, and a highlight block around a run of
       words is the one place the tint reads as a marker pen rather than a target. */
    .tl-mac-app .tl-pm-lgl-a:hover{text-decoration:underline;}
    /* NOT the scrim: it is a backdrop you click to dismiss, not a control, and lighting up the
       whole screen behind a sheet would be absurd. */
    /* THE ARROW, NOT THE HAND. The app says cursor:pointer in 67 places because it was built for
       touch; on a Mac that is the web's hand on things that are not links, which is how a web
       page in a window reads. macOS gives controls the arrow — Finder rows, System Settings
       rows, buttons — and the highlight above is the affordance instead. A real link keeps the
       hand and a field keeps its I-beam. Scoped to #app so sheets are covered too. */
    .tl-mac-app button,.tl-mac-app [data-act],.tl-mac-app [data-reord],.tl-mac-app [data-handle],.tl-mac-app [data-circle],
    .tl-mac-app .tl-row,.tl-mac-app .tl-tile,.tl-mac-app .tl-hero,.tl-mac-app .tl-row2,.tl-mac-app .tl-pvcell{cursor:default;}
    .tl-mac-app a,.tl-mac-app .tl-pm-lgl-a{cursor:pointer;}
    .tl-mac-app input,.tl-mac-app textarea{cursor:text;}
    /* THE DRAG PROXY: the row under the pointer, across both panels (makeDragProxy). Fixed, so the
       list that clips the real row cannot clip it; pointer-events off, so the hit test under the
       pointer finds the bucket beneath rather than this. */
    .tl-mac .tl-dragproxy{position:fixed;left:0;top:0;z-index:80;pointer-events:none;display:flex;align-items:center;gap:10px;box-sizing:border-box;padding:5px 10px;border-radius:12px;background:var(--surface);border:1px solid var(--hair);box-shadow:0 14px 30px rgba(0,0,0,.22);opacity:.97;transform:translate(0,0);}
    .tl-mac .tl-dragsrc{opacity:.32;}
  }
  @media (min-width:600px){
    /* THE MAC'S SETTINGS SOURCE LIST (settingsList: the Mac idiom, Settings full screen, 600 and up):
       the groups on the left, the chosen group's section on the right, the detail its own scroller so a
       group that expands never moves the list. Only the Mac emits .tl-settings-list, so the iPad's two
       columns (the 800 block) and the phone's single column are untouched. */
    .tl-wrap.tl-wrap-list{max-width:none;height:100%;}
    .tl-bview.tl-settings-list{display:flex;flex-direction:column;height:100%;min-height:0;}
    .tl-settings-list .tl-bhead{flex:0 0 auto;}
    .tl-settings-list .tl-slist{flex:1 1 auto;min-height:0;display:grid;grid-template-columns:200px minmax(0,640px);justify-content:start;gap:0 28px;}
    .tl-ssrc{display:flex;flex-direction:column;gap:2px;min-height:0;overflow-y:auto;padding:4px 12px 0 0;border-right:1px solid var(--hair);}
    .tl-ssrc-item{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;text-align:left;padding:7px 10px;border:none;border-radius:8px;background:transparent;color:var(--ink);font-family:inherit;font-size:14px;cursor:default;-webkit-tap-highlight-color:transparent;}
    .tl-ssrc-lbl{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
    /* the pill that says an entry belongs to the subscription — on the three feature groups in
       both states, because what it marks is which entries the plan pays for */
    .tl-spill{flex:0 0 auto;font-size:9.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--accent);background:var(--chipbg);border-radius:5px;padding:2px 5px;line-height:1.3;}
    /* a feature row with nothing to press: the list of what an active plan includes */
    .tl-settings-list .tl-pmopt-st{cursor:default;}
    /* greyed while the plan is inactive — the LABEL only: the pill is the reason and stays legible */
    .tl-ssrc-item.dim .tl-ssrc-lbl{opacity:.45;}
    .tl-spill.off{color:var(--muted);}
    .tl-ssrc-item.sel{background:var(--chipbg);font-weight:600;}
    .tl-sdetail{min-height:0;overflow-y:auto;overflow-x:hidden;overscroll-behavior-x:none;padding-bottom:28px;}
    .tl-sdetail > .tl-sec:first-child{margin-top:4px;}
  }
  @media (max-width:339px){
    /* THE NARROWEST WEBVIEW THE APP CAN BE GIVEN: iPad Split View at one third is 320pt, and with
       the iPad family on, multitasking is mandatory. The phone layout is what renders there, and
       its one casualty is the header date, which at 320 has 41pt and clips to "Sat…". Under 340
       the header wraps: wordmark and icons on the first line, the date on its own line beneath.
       No iPhone the app runs on is this narrow, so the phone render is untouched. */
    .tl-headrow{flex-wrap:wrap;}
    .tl-headdate{flex:1 0 100%;order:3;text-align:left;padding:8px 0 0 2px;}
  }
