/* ═══════════════════════════════════════════════════════════════
   Calendar page components (Home). Needs tokens.css.
   One tear-off sheet per day: month · date · weekday · 3 tasks ·
   the "now" line · a thin progress line · day navigation.
   ═══════════════════════════════════════════════════════════════ */

/* ── The pad: today's sheet sits on two sheets underneath ── */
.cal-pad { position: relative; margin: var(--space-sm) 0 var(--space-2xl); }
.cal-pad::before, .cal-pad::after {           /* the sheets below, slightly offset: a real pad */
  content: ""; position: absolute; inset: 0; border-radius: var(--r-sm);
  background: var(--surface); border: 1px solid var(--line);
}
.cal-pad::before { transform: translate(5px, 7px) rotate(0.8deg); }
.cal-pad::after  { transform: translate(-3px, 4px) rotate(-0.5deg); }

.cal {
  position: relative; z-index: 1;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: var(--space-xl) var(--space-xl) var(--space-lg);
  transform-origin: 50% 0;
  touch-action: pan-y;               /* horizontal swipe = change day */
}
/* binding strip + perforation holes along the top edge */
.cal::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 14px;
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  background:
    radial-gradient(circle at 50% 55%, var(--paper) 0 3.2px, transparent 3.8px) 6px 0 / 18px 14px repeat-x,
    var(--red);
}

/* ── Header: month · year, settings ── */
.cal-head { display: flex; justify-content: space-between; align-items: center; margin-top: var(--space-xs); }
.cal-month { font: 700 var(--t-md)/1.4 var(--f-head); color: var(--red-ink); }
.cal-month .yr { font-family: var(--f-num); font-weight: 600; color: var(--ink-2); margin-left: 6px; }
.cal-head .gear { margin-right: calc(var(--space-sm) * -1); }

/* ── The date ── */
.cal-date {
  display: grid; justify-items: center; position: relative;
  margin: var(--space-xs) 0 var(--space-md);
}
.cal-date .n {
  font: 800 var(--t-date)/0.9 var(--f-num); letter-spacing: -0.04em; color: var(--red);
  font-variant-numeric: lining-nums;
}
.cal-date .dow { font: 700 var(--t-lg)/1.6 var(--f-head); color: var(--ink); margin-top: var(--space-xs); }
.cal-date .greet { font-size: var(--t-sm); color: var(--ink-2); }
.cal.past .cal-date .n, .cal.future .cal-date .n { color: var(--ink-2); }

/* Shot-day stamp: a rubber stamp in the corner, not a banner */
.cal-stamp {
  position: absolute; right: -10px; top: -6px;
  width: 100px; height: 100px; border-radius: 50%;
  display: grid; place-items: center; text-align: center;
  border: 4px double var(--red); color: var(--red-ink);
  font: 700 var(--t-sm)/1.4 var(--f-body);
  transform: rotate(-12deg) scale(1); opacity: .92;   /* matches @keyframes restamp */
  background: color-mix(in oklch, var(--surface) 70%, var(--red-soft));
}
.cal-stamp b { display: block; font-size: 1.6rem; line-height: 1.15; }
.cal-stamp.done { border-color: var(--leaf); color: var(--leaf-ink); background: var(--leaf-soft); }
.cal-stamp.done.fresh { animation: restamp var(--dur-stamp) var(--ease-stamp) both; }   /* weekly: the shot stamp re-lands */
@keyframes restamp { from { opacity: 0; transform: rotate(-24deg) scale(1.3); } }

/* Rules: a dashed tear line between parts */
.cal-rule { border: 0; border-top: 1.5px dashed var(--line); margin: var(--space-md) calc(var(--space-xl) * -1); }

/* ── The 3 tasks ── */
.tasks-title { font: 700 var(--t-sm)/1.5 var(--f-body); color: var(--ink-2); margin: 0 0 var(--space-xs); }
.tasks { list-style: none; margin: 0; padding: 0; display: grid; }
.task {
  display: grid; grid-template-columns: 34px 1fr auto; align-items: center; gap: var(--space-md);
  min-height: 64px; padding: var(--space-xs) 0;
  border-bottom: 1px solid var(--line);
}
.task:last-child { border-bottom: 0; }
.task .no {
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  border: 2px solid var(--red); color: var(--red); font: 800 var(--t-sm)/1 var(--f-num);
}
.task .what { font-weight: 700; line-height: 1.55; }
.task .what small { display: block; font-weight: 400; font-size: var(--t-sm); color: var(--ink-2); }
.task .box {                         /* the tick box: one tap */
  width: 52px; height: 52px; border-radius: var(--r-sm); border: 2.5px solid var(--line);
  background: var(--surface); display: grid; place-items: center; cursor: pointer; padding: 0;
}
.task .box svg { width: 30px; height: 30px; fill: none; stroke: var(--surface); stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 24; stroke-dashoffset: 24; }
.task.done .box { background: var(--leaf); border-color: var(--leaf); }
.task.done .box svg { stroke-dashoffset: 0; }
.task.done .no { background: var(--leaf); border-color: var(--leaf); color: var(--surface); }
.task.done .what { color: var(--ink-2); }
/* partial progress (protein 2/3, water 5/8): dots instead of a box */
.task .dots { display: flex; gap: 6px; align-items: center; }
.task .dots i { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--leaf); }
.task .dots i.on { background: var(--leaf); }
/* The tick he just tapped on the sheet (".fresh" from ui/core.js): box fills, tick draws, newest dot pops.
   Unticking is a correction: it just snaps. Under reduced motion the fill and tick stay (no travel). */
.task.done .box.fresh { animation: box-fill var(--dur-fast) var(--ease-out); }
@keyframes box-fill { from { background: var(--surface); border-color: var(--line); } }
.task.done .box.fresh svg { animation: tick-draw 280ms var(--ease-out) 60ms both; }
.task .dots.fresh i.on:is(:last-child, :has(+ i:not(.on))) { animation: dot-pop var(--dur-fast) var(--ease-out); }
button.dots { border: 0; background: none; padding: 0 0 0 var(--space-sm); min-height: var(--hit); cursor: pointer; flex-wrap: wrap; max-width: 120px; justify-content: flex-end; }
.task .what-link { color: inherit; text-decoration: none; display: block; }
.task .what-link .chev-i { color: var(--ink-2); font-weight: 400; margin-left: 4px; }
.tasks.plan-only .task { min-height: 56px; }
.task.urgent .no { background: var(--red); color: var(--surface); }
.task.urgent .what { color: var(--red-ink); }

/* ── "Now" line ── */
.cal-now {
  display: grid; grid-template-columns: 1fr auto; column-gap: var(--space-md); row-gap: 2px; align-items: center;
  padding: var(--space-md) var(--space-lg); margin-top: var(--space-md);
  border-radius: var(--r-md); background: var(--red-soft); color: var(--ink); text-decoration: none;
  min-height: var(--hit-yn);
}
.cal-now .k { font: 700 var(--t-sm)/1.3 var(--f-body); color: var(--red-ink); }
.cal-now .v { font-weight: 700; line-height: 1.5; }
.cal-now .k, .cal-now .v { grid-column: 1; }
.cal-now .chev, .cal-now > span:last-child:not(.v) { grid-column: 2; grid-row: 1 / span 2; }
.cal-now .chev { color: var(--red-ink); font-size: 1.4rem; }
.cal-now.alert { background: var(--alert-soft); }
.cal-now.alert .k { color: var(--alert); }
/* his answer changed the "now" line: a warm gold wash fades back, so he notices the son listened (P1-6) */
.cal-now.fresh { animation: now-swap var(--dur-slow) var(--ease-out); }
@keyframes now-swap { from { background: var(--gold-soft); } }
.cal-now.fresh .v { animation: view-fade var(--dur) var(--ease-out) both; }

/* ── Thin progress line ── */
.cal-prog { display: grid; grid-template-columns: auto 1fr auto; gap: var(--space-md); align-items: center; margin-top: var(--space-lg); text-decoration: none; color: inherit; }
.cal-prog .a, .cal-prog .b { font: 800 var(--t-md)/1 var(--f-num); }
.cal-prog .b { color: var(--leaf-ink); }
.cal-prog .track { height: 8px; border-radius: var(--r-pill); background: var(--sunk); overflow: hidden; }
.cal-prog .track i { display: block; height: 100%; background: var(--leaf); border-radius: inherit; }
.cal-prog .cap { grid-column: 1 / -1; font-size: var(--t-sm); color: var(--ink-2); margin-top: -4px; }

/* ── Day navigation ── */
.cal-nav { display: flex; justify-content: space-between; align-items: center; margin-top: var(--space-md); }
.cal-nav button {
  min-width: var(--hit); min-height: var(--hit); border: 0; background: none; border-radius: var(--r-pill);
  color: var(--ink-2); font: 600 var(--t-sm)/1 var(--f-body); cursor: pointer; padding: 0 var(--space-md);
}
.cal-nav button:disabled { opacity: .35; }
.cal-nav .today-btn { color: var(--red-ink); font-weight: 700; }
/* Day change (P1-2): the new sheet comes in from the side of the day it is (--dir: -1 earlier, 1 later).
   The two sheets underneath (.cal-pad::before/::after) stay still: they're the pad. */
.cal.day-in, .cal-done.day-in { animation: day-in var(--dur) var(--ease-out) backwards; }
@keyframes day-in { from { opacity: 0; transform: translateX(calc(var(--dir, 0) * var(--enter-x))); } }

/* Yesterday: what he did (read-only, never red) */
.did-list { display: flex; flex-wrap: wrap; gap: var(--space-sm); }
.did-list span { padding: 6px 12px; border-radius: var(--r-pill); background: var(--leaf-soft); color: var(--leaf-ink); font-weight: 600; font-size: var(--t-sm); }
.did-list span.miss { background: var(--sunk); color: var(--ink-2); }

/* ── Tear-off (P1-3): the gold "done" sheet is already underneath; today's sheet rips away from the
   binding's top-left, its bottom edge curling toward him (rotateX under perspective). ui/home.js tearOff(). ── */
.cal.tearing {
  position: absolute; inset: 0 0 auto 0; z-index: 2; transform-origin: 0 0;
  animation: tear var(--dur-slow) var(--ease-sheet) forwards; pointer-events: none;
}
@keyframes tear {
  0%   { transform: none; }
  20%  { transform: perspective(900px) rotateX(8deg) rotate(-2deg) translateY(-4px); }   /* right side lifts: the tear starts */
  100% { transform: perspective(900px) rotateX(24deg) rotate(-16deg) translate(-6%, -115%); opacity: 0; }
}
.cal-done {
  position: relative; z-index: 1;
  background: var(--gold-soft); border: 1px solid var(--gold); border-radius: var(--r-sm);
  padding: var(--space-2xl) var(--space-xl); text-align: center;
  touch-action: pan-y;               /* swipe = change day, like the sheet */
}
.cal-done .seal {
  width: 112px; height: 112px; margin: 0 auto var(--space-lg); border-radius: 50%;
  display: grid; place-items: center; background: var(--gold); color: var(--ink);
  font: 800 2.6rem/1 var(--f-num); box-shadow: inset 0 0 0 6px var(--gold-soft), inset 0 0 0 8px var(--gold);
  transform: scale(1) rotate(-8deg);   /* same function list as @keyframes stamp, so it interpolates cleanly */
}
/* the seal stamps down as the torn sheet clears; the words follow */
.cal-done.fresh .seal { animation: stamp var(--dur-stamp) var(--ease-stamp) 400ms both; }   /* review: 500→400, no empty-sheet beat after the tear clears */
.cal-done.fresh h2, .cal-done.fresh > p { animation: view-fade var(--dur) var(--ease-out) 550ms both; }
.cal-done h2 { margin: 0; font-size: var(--t-xl); }
.cal-done p { color: var(--ink-2); margin: var(--space-sm) 0 0; }
.cal-done .streak-n { font: 800 var(--t-lg)/1 var(--f-num); color: var(--gold-ink); }

/* ── Section header on other screens: a calendar strip ── */
.strip { display: flex; align-items: baseline; gap: var(--space-sm); padding-bottom: var(--space-sm); border-bottom: 3px solid var(--red); margin-bottom: var(--space-lg); }
.strip h1 { font-size: var(--t-xl); }
.strip .sub { margin-left: auto; font-size: var(--t-sm); color: var(--ink-2); }

/* Reduced motion = stamp only, no curl: tearOff() skips the tear; the gold sheet fades in and the seal
   fades (stamp keyframe is opacity-only there, see styles.css). */
@media (prefers-reduced-motion: reduce) {
  .cal.tearing { animation: none; opacity: 0; }
  .cal-done.fresh { animation: view-fade var(--dur) var(--ease-out) both; }
  .cal-done.fresh .seal { animation-delay: 120ms; }
  .cal-done.fresh h2, .cal-done.fresh > p { animation-delay: 200ms; }
  @keyframes restamp { from { opacity: 0; } }
}

/* Coach line (LLM, via nowSuggestion().coach): looks like the son's note, not a bot */
.cal-now.coach { background: var(--surface); border: 1.5px dashed var(--red-line); }
.cal-now.coach .v { font-family: var(--f-head); font-weight: 600; }

/* ── Delight pass (docs/motion-plan.md §9) ── */
/* Next morning's sheet, before he starts: yesterday was a full page. Quiet gold, gone at the first tick. */
.cal-yday { margin: 0 0 var(--space-sm); font-size: var(--t-sm); font-weight: 700; color: var(--gold-ink); }
/* Gold sheet: tomorrow's page, a perforated slip at the bottom (fades in with the words, via .cal-done.fresh > p). */
.cal-done .cal-next {
  margin: var(--space-xl) 0 0; padding-top: var(--space-md); border-top: 2px dotted var(--gold);
  display: flex; flex-direction: column; gap: 2px; color: var(--ink);
}
.cal-next .k { font-size: var(--t-sm); color: var(--gold-ink); font-weight: 700; }
.cal-next .v { font-weight: 600; }
/* The milestone of the day sits on the progress line; the 🎉 stamps once when he reaches it on Home. */
.cal-prog .cap.ms { color: var(--gold-ink); font-weight: 700; }
.cal-prog .stamp-i { display: inline-block; font-weight: 400; }
.cal-prog .stamp-i.fresh { animation: stamp var(--dur-stamp) var(--ease-stamp) 120ms both; }

/* ── Decisions (14 Nov 2026) ── */
/* Safety copy under the now line (dizzy / unwell / pain): calm, readable, not an alarm. */
.cal-care { margin: var(--space-sm) 0 0; padding: var(--space-sm) var(--space-lg); border-radius: var(--r-md);
  background: var(--sunk); font-size: var(--t-sm); line-height: 1.7; color: var(--ink); }
.cal-care.fresh { animation: view-fade var(--dur) var(--ease-out) both; }
/* Shot site: a quiet link in the shot row's subtitle opens the 6 sites in place. */
.task .site-pick { grid-column: 2 / -1; }
/* inline in the row's subtitle; the hit area grows to 48px without growing the row */
.task small .site-toggle { font-size: inherit; min-height: 0; padding: 12px 6px; margin: -12px -6px; text-decoration: underline; text-underline-offset: 3px; }
.task .site-pick { padding: 0 0 var(--space-sm); }
.task .site-pick p { margin: 0 0 var(--space-xs); }
.task .site-pick .chip { min-height: var(--hit); }
.task .site-pick.fresh { animation: ack-in var(--dur) var(--ease-out) both; }
.task small.fresh { animation: view-fade var(--dur) var(--ease-out) both; }

/* Short screens (≤700px tall, or 320 wide): the date numeral sits beside the weekday instead of above it,
   so the "now" line clears the tab bar at 375×667 and 320×640. Still the red calendar date, just smaller. */
@media (max-height: 700px), (max-width: 340px) {
  .cal { padding-top: var(--space-lg); }
  .cal-date {
    grid-template-columns: auto 1fr; justify-items: start; align-items: center;
    column-gap: var(--space-md); margin: 0 0 var(--space-xs);
  }
  .cal-date .n { grid-row: 1 / span 2; font-size: 4.5rem; }
  .cal-date:has(.cal-stamp) { padding-right: 56px; }      /* the stamp sits in the corner, beside the words */
  .cal-date .dow { margin-top: 0; line-height: 1.4; align-self: end; }
  .cal-date .greet { align-self: start; }
  .cal-stamp { width: 64px; height: 64px; top: 0; right: -8px; font-size: 0.72rem; line-height: 1.25; border-width: 3px; }
  .cal-stamp b { font-size: 1.05rem; }
  /* a linked row's detail (the routine's move list) is one tap away: 2 lines here */
  .task .what-link small { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
  .cal-now { margin-top: var(--space-sm); }
  .tasks-title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }   /* the numbered rows say it; screen readers still hear it */
  .cal-rule { margin-top: var(--space-sm); margin-bottom: var(--space-sm); }
}
@media (max-width: 340px) {   /* 320 wide: more room for the task words, so rows wrap less */
  .cal { padding-left: var(--space-lg); padding-right: var(--space-lg); }
  .cal-rule { margin-left: calc(var(--space-lg) * -1); margin-right: calc(var(--space-lg) * -1); }
  .task { grid-template-columns: 30px 1fr auto; gap: var(--space-sm); padding: 2px 0; }
  .cal-now { padding: var(--space-sm) var(--space-md); }
  .cal-pad { margin-top: 0; }
  .cal-head { margin-top: 0; height: 40px; }                 /* the gear keeps its 48px target, overlapping the padding */
  .cal-date .n { font-size: 4rem; }
}

/* ── Polish pass: past-day sheet bits (were inline styles) ── */
.cal-empty { margin: 0; }
.cal-torn { margin: var(--space-md) 0 0; color: var(--gold-ink); font-weight: 700; }
.did-list.center { justify-content: center; margin-top: var(--space-lg); }
