.day {
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  top: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  gap: 2px;
  /* Prevent unusual content (long decimals, etc.) from expanding the
     grid column and breaking the 7-up layout. Don't add overflow:hidden
     here — the met-day pill (.day[data-state="met"]::before) intentionally renders
     outside the tile bounds. */
  min-width: 0;
  /* Lift/press via `top` rather than `transform` so .day doesn't become a
     stacking context root on hover/active — transform creates a stacking
     context which would promote .day[data-state="met"]::before (z:-1) on top of the
     tile's own bg, erasing the colored met tile during hover. */
  transition: top 0.1s ease, box-shadow 0.1s ease;
  box-shadow: var(--shadow-chunky-rest) var(--border);
}

.day:hover {
  top: -2px;
  box-shadow: var(--shadow-chunky-lifted) var(--border);
  z-index: 10;
}

.day:active {
  top: 4px;
  box-shadow: none;
}

.day__note-dot {
  position: absolute;
  top: 6px;
  left: 6px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-muted);
  opacity: 0.7;
  pointer-events: none;
}

.day[data-state="met"] .day__note-dot,
.day[data-month="today"] .day__note-dot {
  background: var(--neutral-0);
  opacity: 0.85;
}

.day[data-month="other"] {
  cursor: pointer;
  background: color-mix(in srgb, var(--surface) 60%, var(--bg));
  border-color: color-mix(in srgb, var(--border) 60%, var(--surface));
  box-shadow: var(--shadow-chunky-rest) color-mix(in srgb, var(--border) 60%, var(--surface));
}

.day[data-month="other"]:hover {
  box-shadow: var(--shadow-chunky-lifted) color-mix(in srgb, var(--border) 60%, var(--surface));
}

.day[data-month="other"]:active {
  box-shadow: none;
}

.day[data-month="other"][data-state="met"] {
  background: color-mix(in srgb, var(--day-met-bg) 60%, var(--surface));
  border-color: color-mix(in srgb, var(--day-met-border) 60%, var(--surface));
  box-shadow: var(--shadow-chunky-rest) color-mix(in srgb, var(--day-met-border) 60%, var(--surface));
}

.day[data-month="other"][data-state="met"]:hover {
  box-shadow: var(--shadow-chunky-lifted) color-mix(in srgb, var(--day-met-border) 60%, var(--surface));
}

.day[data-month="other"][data-state="met"]:active {
  box-shadow: none;
}

.day[data-month="other"][data-state="partial"] {
  background: color-mix(in srgb, var(--unmet-bg) 60%, var(--surface));
  border-color: color-mix(in srgb, var(--unmet-border) 60%, var(--surface));
  box-shadow: var(--shadow-chunky-rest) color-mix(in srgb, var(--unmet-border) 60%, var(--surface));
}

.day[data-month="other"][data-state="partial"]:hover {
  box-shadow: var(--shadow-chunky-lifted) color-mix(in srgb, var(--unmet-border) 60%, var(--surface));
}

.day[data-month="other"][data-state="partial"]:active {
  box-shadow: none;
}

.day[data-month="other"] .day__number,
.day[data-month="other"] .day__value {
  opacity: 0.5;
}

/* Today — colored border only; fill added when goal is met */
.day[data-month="today"] {
  background: var(--surface);
}

.day[data-month="today"][data-state="met"] {
  background: var(--day-met-bg);
}


/* Days with an entry but goal not met — tinted from the active project color
   via body[data-color]'s --unmet-* vars. */
.day[data-state="partial"] {
  border-color: var(--unmet-border);
  background: var(--unmet-bg);
  box-shadow: var(--shadow-chunky-rest) var(--unmet-border);
}

.day[data-state="partial"]:hover {
  box-shadow: var(--shadow-chunky-lifted) var(--unmet-border);
}

.day[data-state="partial"]:active {
  box-shadow: none;
}

/* Met days — individual tiles with a soft highlight pill drawn behind
   consecutive met tiles. Tile bg and highlight come from the active
   body[data-color]'s --day-met-* vars. */
.day[data-state="met"] {
  background: var(--day-met-bg);
  border-color: var(--day-met-border);
  box-shadow: var(--shadow-chunky-rest) var(--day-met-border);
  border-radius: var(--radius);
}

.day[data-state="met"]:hover {
  box-shadow: var(--shadow-chunky-lifted) var(--day-met-border);
  /* Override .day:hover { z-index: 10 } — once .day becomes a stacking context
     root its ::before (z:-1) paints on top of the tile's own bg/border, which
     erases the colored tile and leaves only the pill visible. Keeping z-index
     auto lets the pseudo stay below the tile. */
  z-index: auto;
}

.day[data-state="met"]:active {
  box-shadow: none;
}

/* Streak halo pill behind streak tiles. JS adds .is-streak based on
   goalPeriod: daily → each day that hit its daily threshold; weekly → every
   day in a row whose week hit the weekly goal (regardless of individual
   day state). Joins with adjacent streak days via .is-streak--left/--right.
   Visible pill thickness = 10px on every side of the tile+shadow. Bottom
   inset is -14px (not -10px) to compensate for the tile's 4px chunky drop
   shadow which paints on top of the pill in that region — without the
   compensation the bottom looks ~6px while the top looks 10px. Horizontal
   20px combined overlaps inside the 16px column gap so adjacent pills in the
   same row join. Vertical 24px combined sits inside the 28px row gap so
   pills in adjacent rows never meet. Sits at z:-1 within the grid's
   stacking context so tiles render on top. */
.day.is-streak::before {
  content: '';
  position: absolute;
  top: -10px;
  right: -12px;
  bottom: -14px;
  left: -12px;
  background: var(--day-met-highlight);
  border-radius: var(--radius);
  z-index: -1;
  pointer-events: none;
  /* Counter the tile's own hover/active shift (see .day:hover / .day:active)
     by adjusting top/bottom so the pill stays in the same viewport position
     while the tile lifts or presses. Transition duration must match .day. */
  transition: top 0.1s ease, bottom 0.1s ease;
}

.day.is-streak:hover {
  /* Same reason as .day[data-state="met"]:hover — prevent z-index: 10 from
     creating a stacking context that would flip ::before above the tile bg.
     Needed for streak cells that aren't met (weekly-mode empty/partial cells
     in a streak row). */
  z-index: auto;
}

.day.is-streak:hover::before {
  top: -8px;
  bottom: -16px;
}

.day.is-streak:active::before {
  top: -14px;
  bottom: -10px;
}

/* Square the inner edges where the pill meets an adjacent streak day, so
   consecutive halos read as one continuous band. */
.day.is-streak.is-streak--left::before {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}

.day.is-streak.is-streak--right::before {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

.day__number {
  position: absolute;
  top: 6px;
  right: 7px;
  font-size: var(--text-md);
  font-weight: var(--font-semibold);
  color: var(--text-muted);
}

.day[data-state="met"] .day__number {
  color: var(--day-met-text);
}

.day[data-state="partial"] .day__number {
  color: var(--unmet-text);
}

.day[data-month="today"] .day__number {
  background: var(--accent);
  color: var(--neutral-0);
  border-radius: 50%;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  top: 4px;
  right: 5px;
}

.day[data-month="today"]:hover .day__number {
  background: transparent;
  color: transparent;
}

.day[data-month="today"][data-state="met"] .day__number {
  background: rgba(255, 255, 255, 0.3);
  color: var(--neutral-0);
}

.day[data-month="today"][data-state="met"]:hover .day__number {
  background: transparent;
  color: transparent;
}

.day__value {
  font-size: var(--text-lg);
  font-weight: var(--font-black);
  color: var(--green);
  line-height: var(--leading-tight);
}

.day[data-state="met"] .day__value {
  color: var(--day-met-text);
}

.day[data-state="partial"] .day__value {
  color: var(--unmet-text);
}

.day[data-month="today"]:not([data-state="met"]) .day__value {
  color: var(--today-text);
}

.day__progress {
  font-size: var(--text-lg);
  font-weight: var(--font-black);
  color: var(--today-text);
  line-height: var(--leading-tight);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Day-off: diagonal stripe pattern. */
.day[data-state="day-off"] { background-clip: padding-box; background-image: repeating-linear-gradient(45deg, transparent, transparent 5px, color-mix(in srgb, var(--neutral-500) 18%, transparent) 5px, color-mix(in srgb, var(--neutral-500) 18%, transparent) 10px); }

/* ── Add button ────────────────────────────── */
.day__add {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  font-size: var(--text-md);
  font-weight: var(--font-extrabold);
  line-height: var(--leading-tight);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: all 0.12s ease;
}

.day:hover .day__add {
  opacity: 1;
}

.calendar-grid.is-tap-mode .day__add {
  display: none;
}

.day__dec {
  position: absolute;
  bottom: 4px;
  left: 50%;
  transform: translateX(-50%);
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1.5px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--font-bold);
  line-height: var(--leading-tight);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: all 0.12s ease;
  z-index: 2;
}
.day:hover .day__dec {
  opacity: 1;
}
.day__dec:hover {
  background: var(--red);
  border-color: var(--red-dark);
  color: var(--neutral-0);
  transform: translateX(-50%) scale(1.15);
}

.day__add:hover {
  background: var(--green);
  border-color: var(--green-dark);
  color: var(--neutral-0);
  transform: scale(1.15);
}

/* ── Day tooltip ───────────────────────────── */
.day__tooltip {
  position: absolute;
  z-index: 500;
  background: var(--neutral-900);
  color: var(--neutral-0);
  border-radius: var(--radius);
  padding: 10px 14px;
  font-size: var(--text-md);
  font-weight: var(--font-normal);
  line-height: var(--leading-normal);
  max-width: 320px;
  pointer-events: none;
}
.tt-section + .tt-section { margin-top: 14px; }
.tt-label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--font-bold);
  text-transform: uppercase;
  letter-spacing: .06em;
  opacity: .6;
  margin-bottom: 2px;
}
.tt-label-inline { font-weight: var(--font-bold); opacity: .6; }
.tt-heading-inline { font-size: var(--text-sm); font-weight: var(--font-bold); text-transform: uppercase; letter-spacing: .08em; color: rgba(255,255,255,0.42); }
.tt-heading {
  font-size: var(--text-sm);
  font-weight: var(--font-bold);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: rgba(255, 255, 255, 0.42);
  margin-bottom: 10px;
}
.tt-note { opacity: .85; }
.tt-task {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  padding: 0;
}
.tt-task-body {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 7px;
}
.tt-bullet { flex-shrink: 0; opacity: .25; line-height: var(--leading-normal); }
.tt-check {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
}
.tt-check svg {
  width: 10px;
  height: 10px;
  stroke: transparent;
}
.tt-done {
  background: var(--green);
  border-color: var(--green);
}
.tt-done svg {
  stroke: var(--neutral-0);
}
.tt-task-text { flex: 1; font-weight: var(--font-bold); line-height: var(--leading-normal); }
.tt-dur {
  font-size: var(--text-sm);
  font-weight: var(--font-normal);
  color: rgba(255, 255, 255, 0.45);
  white-space: nowrap;
  line-height: var(--leading-normal);
}

.tt-session {
  background: rgba(255, 255, 255, 0.04);
  padding: 8px 14px;
  margin: 8px -14px 0;
}

.tt-session--alt {
  background: rgba(255, 255, 255, 0.10);
}

.tt-session + .tt-session { margin-top: 12px; }
.tt-task + .tt-session { margin-top: 12px; }
.tt-session + .tt-task { margin-top: 12px; }
.tt-task + .tt-task { margin-top: 10px; }
.tt-task--indented + .tt-task--indented { margin-top: 4px; }

.tt-session .tt-session-header {
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  margin-bottom: 6px;
}

.tt-clock {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--green);
}

.tt-clock svg {
  width: 16px;
  height: 16px;
}

.tt-row-icon {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.45);
}

.tt-row-icon svg {
  width: 14px;
  height: 14px;
}

.tt-task--alt {
  background: rgba(255, 255, 255, 0.04);
  padding: 4px 14px;
  margin: 0 -14px;
}

.tt-task--indented {
  padding-left: 10px;
}

.tt-task--indented + .tt-task--indented { margin-top: 4px; }
.tt-session-header + .tt-task--indented { margin-top: 0; }

/* ── Daily milestone (day-cell celebration) ───────────── */
/* Avoids transform on .day itself: a transform creates a new stacking context
   on .day which would hide the [data-state="met"]::before background pill during the
   animation (see comment at the top of .day). Animate via box-shadow + an
   ::after overlay instead. */
.day.is-celebrating {
  --day-shadow-color: var(--border);
  animation: day-celebrate-glow 0.65s ease-out;
  z-index: 20;
}

.day.is-celebrating[data-state="met"] {
  --day-shadow-color: var(--day-met-border);
}

.day.is-celebrating::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  pointer-events: none;
  border: 2.5px solid var(--celebrate-color);
  animation: day-celebrate-ring 0.65s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}

@keyframes day-celebrate-glow {
  0%   { box-shadow: var(--shadow-chunky-rest) var(--day-shadow-color), 0 0 0 0 var(--celebrate-color); }
  40%  { box-shadow: var(--shadow-chunky-rest) var(--day-shadow-color), 0 0 0 14px transparent; }
  100% { box-shadow: var(--shadow-chunky-rest) var(--day-shadow-color), 0 0 0 0 transparent; }
}

@keyframes day-celebrate-ring {
  0%   { opacity: 0.9; transform: scale(1); }
  100% { opacity: 0;   transform: scale(1.35); }
}

.day__celebrate-pill {
  position: absolute;
  top: -18px;
  left: 50%;
  padding: 3px 10px;
  font-size: var(--text-sm);
  font-weight: var(--font-extrabold);
  color: var(--neutral-0);
  background: var(--celebrate-color);
  border-radius: var(--radius-pill);
  white-space: nowrap;
  pointer-events: none;
  z-index: 25;
  box-shadow: var(--shadow-chunky-thin) rgba(0, 0, 0, 0.12);
  animation: day-celebrate-pill 1.5s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}

@keyframes day-celebrate-pill {
  0%   { opacity: 0; transform: translate(-50%, 4px) scale(0.8); }
  20%  { opacity: 1; transform: translate(-50%, -4px) scale(1.05); }
  35%  { opacity: 1; transform: translate(-50%, -8px) scale(1); }
  80%  { opacity: 1; transform: translate(-50%, -14px) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -22px) scale(0.95); }
}
