.frog{display:flex;align-items:center;gap:12px;background:rgba(127,176,105,.12);border:1.5px dashed rgba(127,176,105,.55);border-radius:var(--radius-lg);padding:var(--space-3) var(--space-4);cursor:pointer;transition:transform var(--duration-base),box-shadow var(--duration-base);animation:taskIn var(--duration-slow) var(--ease-out)}
.frog:hover{transform:translateY(-2px);box-shadow:var(--shadow-sm)}
.frog-ico{width:42px;height:42px;border-radius:var(--radius-sm);background:var(--surface);display:grid;place-items:center;color:var(--green);flex-shrink:0}
.frog-ico svg{animation:drift 4s ease-in-out infinite}
.frog-txt{flex:1;min-width:0}
.frog-txt strong{display:block;font-family:var(--font-personality);font-size:14px;font-weight:700;color:#5f8f4d;line-height:1.5}
html[data-mode="dark"] .frog-txt strong{color:#9ccc86}
.frog-txt span{display:block;font-size:13px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:2px}
.frog-go{border:none;background:var(--green);color:#fff;font-family:var(--font-ui);font-size:13px;font-weight:600;padding:8px 14px;border-radius:var(--radius-pill);cursor:pointer;box-shadow:0 3px 0 0 rgba(90,130,75,.5);transition:transform var(--duration-fast);flex-shrink:0}
.frog-go:active{transform:translateY(2px);box-shadow:none}
.frog-close{border:none;background:transparent;color:var(--green);opacity:.5;width:26px;height:26px;border-radius:var(--radius-xs);cursor:pointer;display:grid;place-items:center;flex-shrink:0;transition:all var(--duration-fast)}
.frog-close:hover{opacity:1;background:rgba(127,176,105,.2)}

.tasks{list-style:none}
/* ═══ Priority 8.5: Tasks Experience — task information first, controls second ═══ */

.tasks{display:flex;flex-direction:column}
/* Presentation-only grouping: completed tasks sit visually below the active
   group. DOM order stays the single source of truth (drag & drop and
   syncOrder are unaffected — this is pure visual ordering). */
.task{order:1}
.task.done{order:2}

/* contain:layout style: a row's internals (wrapped chips, long titles) can
   never reflow the list around it, so adding, completing or removing one task
   only costs the row. Long lists stay smooth to scroll and to edit. */
.task{position:relative;contain:layout style;display:flex;align-items:center;gap:12px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:14px 18px;margin-bottom:10px;box-shadow:var(--shadow-1);transition:transform var(--duration-fast) var(--ease-out),box-shadow var(--duration-base),opacity var(--duration-base),background var(--duration-slow);animation:taskIn var(--duration-slow) var(--ease-out) backwards}
.task:last-child{margin-bottom:0}
.task:hover{transform:translateY(-1px);box-shadow:var(--shadow-lg)}
.task::after{display:none}
@keyframes taskIn{from{opacity:0;transform:translateY(16px) scale(.96)}}

/* Accent bar: fixed geometry, growth expressed as a composited scale so hover
   never animates top/bottom (motion system: transform over layout properties). */
.task::before{content:'';position:absolute;inset-inline-start:-1px;top:12%;bottom:12%;width:4px;border-radius:var(--radius-pill);background:var(--pr);transform:scaleY(.737);transform-origin:50% 50%;transition:transform var(--duration-base) var(--ease-out)}
.task:hover::before{transform:scaleY(1)}
.task[data-p="high"]{--pr:var(--color-danger)}
.task[data-p="mid"]{--pr:var(--color-warning)}
.task[data-p="low"]{--pr:var(--color-success)}

.grip{color:var(--muted);opacity:.4;cursor:grab;display:grid;place-items:center;flex-shrink:0}
.task.dragging{opacity:.45;transform:scale(1.02);cursor:grabbing}

.pri-dot{width:11px;height:11px;border-radius:50%;background:var(--pr);border:none;cursor:pointer;flex-shrink:0;position:relative;transition:transform var(--duration-fast),background var(--duration-base)}
.pri-dot::after{content:'';position:absolute;inset:-10px;border-radius:50%;display:block}
.pri-dot:hover{transform:scale(1.35)}
/* The "this one matters" halo on high-priority dots.
   It used to animate box-shadow, which is a paint-only property: every
   high-priority row in the list repainted on every frame, for as long as the
   app stayed open. A ring on its own layer that only scales and fades gives
   the same slow breath at no per-frame paint cost. The hold at the end of the
   cycle (70%→100%) is what makes it read as a calm exhale rather than a
   repeating blink. */
.task[data-p="high"] .pri-dot::before{content:'';position:absolute;inset:-2px;border-radius:50%;border:2px solid var(--pr);opacity:0;pointer-events:none;animation:pulse 2.6s ease-in-out infinite}
@keyframes pulse{0%{transform:scale(.85);opacity:.55}70%{transform:scale(2.2);opacity:0}100%{transform:scale(2.2);opacity:0}}
/* Priority change confirms itself with the expanding ring alone — the previous
   scale bounce was the only spring overshoot left in the product. */
.pri-dot.changed{animation:priPulse var(--duration-slow) ease}
@keyframes priPulse{0%{box-shadow:0 0 0 0 var(--pr)}50%{box-shadow:0 0 0 10px transparent}100%{box-shadow:0 0 0 0 transparent}}

.check{width:26px;height:26px;flex-shrink:0;border-radius:var(--radius-xs);border:2px solid var(--muted);background:transparent;cursor:pointer;display:grid;place-items:center;position:relative;transition:background var(--duration-fast) var(--ease-out),border-color var(--duration-fast),box-shadow var(--duration-base) var(--ease-out),transform var(--duration-fast) var(--ease-out)}
/* 44px touch target without visual growth (hit-area only) */
.check::after{content:'';position:absolute;inset:-9px;border-radius:var(--radius-sm)}
.check:hover{border-color:var(--green)}
.check:active{transform:scale(.9)}
.check svg{width:14px;height:14px;stroke:#fff;stroke-width:3;fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:24;stroke-dashoffset:24;transition:stroke-dashoffset var(--duration-fast) ease .05s}
/* Completion sequence: press → checked → reduced visual weight.
   Transform/opacity only — no layout shift. */
.task.done .check{background:var(--green);border-color:transparent;box-shadow:0 4px 10px -5px var(--green);animation:pop var(--duration-base) var(--ease-out)}
.task.done .check svg{stroke-dashoffset:0}

.title{flex:1;min-width:0;font-family:var(--font-ui);font-size:15px;font-weight:500;line-height:1.6;position:relative;transition:color var(--duration-base);word-break:break-word}
.title::after{content:'';position:absolute;inset-inline-start:0;top:55%;height:1.6px;width:100%;background:var(--muted);border-radius:2px;transform:scaleX(0);transform-origin:100% 50%;transition:transform var(--duration-base) var(--ease-out) 50ms}
:dir(ltr) .title::after{transform-origin:0 50%}
/* Completed: visibly quieter group — recessed surface, lighter shadow,
   still fully readable and interactive (no over-fading) */
.task.done{background:var(--color-bg);box-shadow:var(--shadow-0);opacity:.75}
.task.done .title{color:var(--muted);font-weight:400}
.task.done .title::after{transform:scaleX(1)}
.title-input{flex:1;min-width:0;font-family:var(--font-ui);font-size:15px;font-weight:500;border:none;outline:none;background:var(--accent-soft);border-radius:var(--radius-xs);padding:5px 10px;color:var(--text)}

.cat-tag{flex-shrink:0;font-family:var(--font-ui);font-size:11px;font-weight:500;line-height:1.4;color:var(--cc);background:var(--accent-soft);background:color-mix(in srgb,var(--cc) 12%,transparent);border:1px solid transparent;border-color:color-mix(in srgb,var(--cc) 28%,transparent);padding:3px 10px;border-radius:var(--radius-pill);cursor:pointer;transition:transform var(--duration-fast)}
.cat-tag:hover{transform:scale(1.04)}
.cat-tag.flipped{animation:chipFlip var(--duration-base) ease}

.due-chip{flex-shrink:0;font-family:var(--font-ui);font-size:11px;font-weight:500;line-height:1.4;padding:3px 10px;border-radius:var(--radius-pill);border:1px solid transparent;cursor:pointer;transition:transform var(--duration-fast);background:transparent;color:var(--muted)}
.due-chip:hover{transform:scale(1.04)}
.due-chip.none{border:1px dashed var(--border);opacity:.65}
.due-chip.today{color:var(--color-accent-strong);background:var(--accent-soft);border-color:color-mix(in srgb,var(--color-accent) 30%,transparent);font-weight:600}
.due-chip.soon,.due-chip.far{color:var(--color-text-secondary);background:var(--bg);border-color:var(--border)}
.due-chip.late{color:var(--color-danger);background:color-mix(in srgb,var(--color-danger) 10%,transparent);border-color:color-mix(in srgb,var(--color-danger) 32%,transparent);font-weight:600}
html[data-mode="dark"] .due-chip.late{color:#ff8f8f}
.due-chip.flipped{animation:chipFlip var(--duration-base) ease}

.dur-chip{flex-shrink:0;font-family:var(--font-ui);font-size:11px;font-weight:600;line-height:1.4;padding:3px 10px;border-radius:var(--radius-pill);border:1px solid transparent;cursor:pointer;transition:transform var(--duration-fast);color:#7b6fd8;background:color-mix(in srgb,#7b6fd8 10%,transparent);border-color:color-mix(in srgb,#7b6fd8 28%,transparent)}
html[data-mode="dark"] .dur-chip{color:#a79bf5}
.dur-chip:hover{transform:scale(1.04)}
.dur-chip.flipped{animation:chipFlip var(--duration-base) ease}
.dur-chip.none{border:1px dashed var(--border);opacity:.65;background:transparent;color:var(--muted)}
.dur-input{width:82px;font-family:var(--font-ui);font-size:13px;font-weight:600;text-align:center;border:none;outline:none;background:var(--accent-soft);border-radius:var(--radius-xs);padding:4px 10px;color:var(--text)}

@keyframes chipFlip{
  0%{transform:scale(1) rotateY(0)}
  40%{transform:scale(.85) rotateY(90deg)}
  60%{transform:scale(.85) rotateY(90deg)}
  100%{transform:scale(1) rotateY(0)}
}

.focus-btn{border:none;background:transparent;color:var(--muted);width:32px;height:32px;border-radius:var(--radius-xs);cursor:pointer;display:grid;place-items:center;flex-shrink:0;opacity:.55;position:relative;transition:all var(--duration-fast)}
.focus-btn::after{content:'';position:absolute;inset:-6px;border-radius:var(--radius-sm)}
.task:hover .focus-btn{opacity:1}
.focus-btn:hover{color:var(--accent);background:var(--accent-soft);transform:scale(1.12)}
.task.done .focus-btn{display:none}

/* ── Reminder bell (per-task notification switch) ──
   Off: quiet, same family as the focus button. On: accent-tinted so the
   state is readable by color AND shape (filled clapper dot). */
.bell-btn{border:none;background:transparent;color:var(--muted);width:32px;height:32px;border-radius:var(--radius-xs);cursor:pointer;display:grid;place-items:center;flex-shrink:0;opacity:.55;position:relative;transition:all var(--duration-fast)}
.bell-btn::after{content:'';position:absolute;inset:-6px;border-radius:var(--radius-sm)}
.bell-btn:hover{color:var(--accent);background:var(--accent-soft);opacity:1;transform:scale(1.12)}
.bell-btn.on{opacity:1;color:var(--accent)}
.bell-btn.on::before{content:'';position:absolute;bottom:5px;inset-inline-end:5px;width:5px;height:5px;border-radius:50%;background:var(--accent)}
.task.done .bell-btn{display:none}
@media (hover:none){.bell-btn{opacity:.7}}
.bell-btn:focus-visible{outline:2px solid var(--color-focus,var(--accent));outline-offset:2px}
@media (prefers-reduced-motion:reduce){.bell-btn{transition:none}.bell-btn:hover{transform:none}}

.del{border:none;background:transparent;color:var(--muted);width:32px;height:32px;border-radius:var(--radius-xs);cursor:pointer;display:grid;place-items:center;flex-shrink:0;opacity:0;transform:scale(.8);position:relative;transition:all var(--duration-fast)}
.del::after{content:'';position:absolute;inset:-6px;border-radius:var(--radius-sm)}
.task:hover .del{opacity:1;transform:none}
/* Keyboard reaches the button without hovering, so it has to become visible the
   moment it takes focus — otherwise the row offers an invisible deletion target. */
.task:focus-within .del{opacity:1;transform:none}
.del:focus-visible{opacity:1;transform:none;color:var(--danger);outline:2px solid var(--color-focus,var(--accent));outline-offset:2px}
.del:hover{color:var(--danger);background:rgba(228,88,79,.12);transform:scale(1.15)!important}
@media (hover:none){.del{opacity:.6;transform:none}.focus-btn{opacity:.7}}

.task.flash{animation:flash 1.5s ease}
@keyframes flash{0%{box-shadow:0 0 0 0 rgba(244,112,58,0)}25%,60%{box-shadow:0 0 0 5px var(--accent-soft),var(--shadow-lg)}100%{box-shadow:var(--shadow-sm)}}

/* ── Empty state: human and calm, never error-like (8.5) ── */
.empty{text-align:center;padding:28px 10px;color:var(--muted);font-family:var(--font-personality);font-size:16px;font-weight:700;animation:fadeUp var(--duration-slow) ease;line-height:1.7}
.empty-add{margin-top:12px;border:1.5px dashed color-mix(in srgb,var(--color-accent) 45%,transparent);background:transparent;color:var(--color-accent);font-family:var(--font-ui);font-size:13px;font-weight:600;padding:10px 22px;border-radius:var(--radius-pill);cursor:pointer;transition:all var(--duration-fast)}
.empty-add:hover{background:var(--accent-soft);border-style:solid}
.empty .art{display:inline-block;animation:drift 5s ease-in-out infinite;margin-bottom:12px;color:var(--accent)}
.empty .art[hidden]{display:none}
.empty .art svg{max-width:100%;height:auto}
.empty .fill-soft{fill:var(--accent-soft)}
.empty .stroke-a{stroke:currentColor}
.empty .fill-a{fill:var(--accent)}
.empty .fill-d{fill:var(--danger)}
.spark{transform-box:fill-box;transform-origin:center;animation:twinkle 4s ease-in-out infinite}
.spark.s2{animation-delay:1.1s}
@keyframes fadeUp{from{opacity:0;transform:translateY(10px)}}

.list-footer{display:flex;justify-content:space-between;align-items:center;gap:8px;color:var(--muted);font-family:var(--font-ui);font-size:12px;font-weight:500;padding:0 6px;flex-wrap:wrap}
.clear-btn{border:none;background:none;color:var(--muted);font-family:var(--font-ui);font-size:12px;font-weight:500;cursor:pointer;transition:color var(--duration-fast)}
.clear-btn:hover{color:var(--danger)}

/* ═══ Undo Toast (component contract: .toast in components2.css) ═══ */

.app:has(.focus-pill:not([hidden])) .list-footer{padding-bottom:60px}

/* ═══ Task row layout ═══
   The row is arranged for the width it actually has, not for the size of the
   screen. The content column is capped at 480px at every viewport (see .app in
   base.css), so on a wide screen a single line still has to share ~440px with
   nine controls: the title then holds a few pixels and wraps one character per
   line. The compact two-row arrangement is therefore the row's own layout at
   every size — Row 1: checkbox + title + the row's own controls; Row 2:
   metadata + actions. (.task::after below is a zero-height line break, not
   decoration.) */
.task{flex-wrap:wrap;row-gap:8px;column-gap:10px}
.task::after{content:'';display:block;order:4;flex-basis:100%;height:0}
.check{order:0}
.title{order:1}
.del{order:2}
.focus-btn{order:3}
.bell-btn{order:3}
.pri-dot{order:5;margin-inline-start:34px}
.cat-tag{order:6}
.due-chip{order:7}
.dur-chip{order:8}

/* ═══ Responsive: Tasks ═══
   Compact scale for genuinely small screens. The arrangement above never
   changes at a breakpoint — only sizes do — so a row can't rearrange itself
   around a title that has no room left. */
@media (max-width:480px){
  .task{padding:12px 14px;margin-bottom:8px;border-radius:var(--radius-md)}
  .grip{display:none}
  .check{width:24px;height:24px}
  .check::after{inset:-10px}
  .title{font-size:14px}
  .del{opacity:.7;transform:none;width:28px;height:28px}
  .del::after{inset:-8px}
  .focus-btn{opacity:.7;width:28px;height:28px}
  .focus-btn::after{inset:-8px}
  .bell-btn{opacity:.7;width:28px;height:28px}
  .bell-btn::after{inset:-8px}
  .pri-dot::after{inset:-12px}
  .cat-tag{font-size:10px;padding:2px 8px}
  .due-chip{font-size:10px;padding:2px 8px}
  .dur-chip{font-size:10px;padding:2px 8px}
  .frog{padding:10px 12px;gap:10px}
  .frog-ico{width:36px;height:36px;border-radius:var(--radius-xs)}
  .frog-ico svg{width:22px;height:22px}
  .frog-txt strong{font-size:13px}
  .frog-txt span{font-size:12px}
  .frog-go{font-size:12px;padding:7px 12px}
  .empty{padding:22px 8px;font-size:15px}
  .empty .art svg{width:84px}
  .list-footer{font-size:11px}
  .clear-btn{font-size:11px}
}
@media (max-width:360px){
  .task{column-gap:8px;padding:11px 12px}
  .check{order:0;width:22px;height:22px}
  .check::after{inset:-12px}
  .title{font-size:13px}
  .del,.focus-btn{width:26px;height:26px}
  .del::after,.focus-btn::after{inset:-9px}
  .pri-dot{margin-inline-start:30px}
  .cat-tag,.due-chip,.dur-chip{font-size:9px;padding:2px 7px}
  .empty .art svg{width:72px}
}