/* --- Calendar card -------------------------------------------------------- */

.col-calendar .card-head {
  flex-wrap: wrap;
  row-gap: 8px;
}

/* The window onto the strip. Both grids are longer than it in the direction
   they run, and the scrolling is the browser's own — nothing here snaps.
   A query container, so a day column can be a seventh of *this* rather than a
   seventh of a strip that is seven weeks wide. */
.cal {
  container-type: inline-size;
  flex: 1;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
}

/* This is the one scroller in the app with bars on both axes, so it is the one
   that gets a scrollbar corner — a square in the bottom right, sitting exactly
   where the card's radius clips it. base.css makes that transparent along with
   every other track. */

/* --- header controls ------------------------------------------------------ */

/* A segmented control, macOS style: the selected segment is a raised lozenge
   inside a recessed track, not a colored tab. */
.seg {
  display: flex;
  gap: 2px;
  flex: none;
  padding: 2px;
  border-radius: var(--r-pill);
  background: var(--fill-2);
}

.seg-btn {
  padding: 3px 11px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: 550;
  color: var(--muted);
  cursor: pointer;
  transition: background .16s ease, color .16s ease;
}

.seg-btn:hover { color: var(--ink-2); }

.seg-btn.on {
  color: var(--ink);
  background: var(--fill);
  box-shadow: 0 1px 2px rgba(20, 30, 45, .12), inset 0 1px 0 var(--glass-hi);
}

.navset {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: none;
}

/* Scoped under .navset on purpose: a bare `.nav` here would collide with the
   sidebar's <nav class="nav"> container, which loads earlier and would lose. */
.navset .step {
  display: grid;
  place-content: center;
  width: 24px;
  height: 24px;
  border-radius: var(--r);
  color: var(--muted);
  cursor: pointer;
}

.navset .step-text {
  padding: 3px 9px;
  border-radius: var(--r);
  font-size: 11px;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}

.navset .step:hover,
.navset .step-text:hover { background: var(--hover); color: var(--ink); }

/* --- week ----------------------------------------------------------------- */

/* One flex row of full-height day columns, not a grid with a cell per pane.
   `position: sticky` clamps a box to its containing block, and for a grid item
   that is its own grid area — so an hour rail in a 54px cell has nowhere to
   travel, and neither does a heading in a 54px row. Here the rail's containing
   block is the whole frame and a heading's is its own tall column, so both have
   the room they need to stay put. */
.cal-week {
  --hr: 46px;
  --head-h: 54px;
  --lane-h: 32px;
  --gutter: 54px;
  --daycol: 132px;
  display: flex;
  align-items: flex-start;
  /* Load-bearing. Left to size itself the frame would be as wide as the card,
     and the rail's containing block with it — putting the sticky rail back in a
     box it cannot travel across, which is the bug this layout exists to fix. */
  width: max-content;
}

/* A column is exactly a seventh of the *card* — not of the strip, which is
   seven weeks wide — so seven of them fill the window and the rest waits off
   both edges. The floor keeps a column usable in a narrow window, where the
   strip simply starts scrolling sooner.
   Guarded rather than declared with a plain fallback above it: a custom
   property accepts any token stream, so an unsupported `cqw` would still
   override the fallback and leave the columns with no width at all. */
@supports (width: 1cqw) {
  .cal-week { --daycol: max(96px, (100cqw - var(--gutter)) / 7); }
}

/* ── On the frozen panes ──────────────────────────────────────────────────
   The rail, the day headings and the all-day lanes all stay put while the grid
   moves under them, and every one of them is painted on `--sticky`, which is
   opaque. It has to be: a pane exists to hide what passes beneath it, and at
   even 88% the hour grid reads straight through — legibly enough that blocks
   look like they have climbed up into the dates.

   That went unnoticed until now only because sticky did not actually work here
   before, so nothing ever passed underneath. None of these carry a
   backdrop-filter either: behind an opaque surface it renders nothing, and
   there are two of them per day, which across the strip is around a hundred
   blurred layers for the compositor to keep alive for no visible result. */

/* The frozen left-hand pane. Above everything, because it covers whichever day
   has been scrolled under it. */
.wk-rail {
  position: sticky;
  left: 0;
  z-index: 8;
  flex: none;
  width: var(--gutter);
  background: var(--sticky);
}

.wk-daycol {
  flex: none;
  width: var(--daycol);
}

/* The two corners above the hour labels, each frozen against its own row. */
.wk-corner {
  position: sticky;
  top: 0;
  z-index: 2;
  height: var(--head-h);
  background: var(--sticky);
  border-bottom: 1px solid var(--hair);
}

.wk-corner.lane {
  top: var(--head-h);
  z-index: 1;
  height: var(--lane-h);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 7px;
  font-size: 9px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--faint);
}

/* `width: 100%` is doing real work. This is a <button>, and a form control
   resolves `width: auto` to shrink-to-fit no matter what `display` says — so it
   sizes to "MON 3" and leaves most of the column uncovered. As a grid item it
   used to be stretched to its cell for free; as a block child of a flex column
   nothing stretches it, and the gap it left was a window onto the hour grid
   scrolling underneath. */
.wk-day {
  position: sticky;
  top: 0;
  z-index: 6;
  width: 100%;
  height: var(--head-h);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  background: var(--sticky);
  border-bottom: 1px solid var(--hair);
  cursor: pointer;
}

.wk-day .dow {
  font-size: 9.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--faint);
}

.wk-day .dnum {
  display: grid;
  place-content: center;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  color: var(--ink-2);
}

.wk-day:hover .dnum { background: var(--hover); }
.wk-day.is-sel .dnum { box-shadow: inset 0 0 0 1.5px var(--ink-2); }

/* Today is the one place the accent appears in the grid chrome. */
.wk-day.is-today .dow { color: var(--accent-ink); }
.wk-day.is-today .dnum {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  box-shadow: none;
}

/* --- all-day lane --------------------------------------------------------- */

/* A fixed height across the strip, set from the busiest day in it: unequal
   lanes would walk the hour bodies out of line with each other. Past four
   entries the lane scrolls rather than eating the day. */
.wk-lane {
  position: sticky;
  top: var(--head-h);
  z-index: 5;
  height: var(--lane-h);
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 3px 4px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  background: var(--sticky);
  border-bottom: 1px solid var(--hair);
  box-shadow: inset 1px 0 0 var(--line-2);
  cursor: pointer;
}

.wk-lane::-webkit-scrollbar { display: none; }

.wk-lane.is-over {
  background: var(--accent-bg);
  box-shadow: inset 0 0 0 1.5px var(--accent);
}

/* --- hour body ------------------------------------------------------------ */

.hr-label {
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  height: var(--hr);
  padding: 3px 7px 0 0;
  font-size: 9.5px;
  color: var(--faint);
}

/* Hour rules are painted by the column rather than built out of fifteen empty
   divs: one week of those was affordable, a strip of seven weeks is six hundred
   nodes rebuilt every time a checkbox is ticked. The line sits at the *bottom*
   of each band, which keeps the top edge clean without a special case for the
   first one, and a gradient adds no height the way a border would — the blocks
   are positioned as a percentage of the column and would walk out of step. */
.wk-col {
  position: relative;
  height: calc(var(--hours) * var(--hr));
  box-shadow: inset 1px 0 0 var(--line-2);
  cursor: pointer;
  /* Dragging a length out would otherwise sweep a text selection across the
     grid, and there is nothing in a column worth selecting. */
  user-select: none;
  -webkit-user-select: none;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0 calc(var(--hr) - 1px),
    var(--line-2) calc(var(--hr) - 1px) var(--hr)
  );
}

/* background-color, not the shorthand: the shorthand would wipe the hour rules. */
.wk-col.is-sel { background-color: var(--fill-2); }
.wk-col.is-over { background-color: var(--hover); }

/* --- blocks --------------------------------------------------------------- */

/* A pale slab with a colored edge: legible over the hour rules behind it, and
   the edge is where the project's color lands. */
.wk-block {
  position: absolute;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 5px;
  overflow: hidden;
  padding: 2px 6px 3px;
  border-radius: 7px;
  background: var(--tint-bg);
  cursor: grab;
  box-shadow:
    inset 2px 0 0 var(--tint),
    inset 0 0 0 1px var(--hair),
    0 1px 2px rgba(20, 30, 45, .10);
}

.wk-block:hover {
  box-shadow:
    inset 2px 0 0 var(--tint),
    inset 0 0 0 1px var(--tint),
    0 2px 6px rgba(20, 30, 45, .14);
}

.wk-block.is-pending { opacity: .55; cursor: default; }

.wk-block .b-time {
  flex: none;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 9.5px;
  font-weight: 600;
  color: var(--tint);
}

.wk-block .b-name {
  font-size: 11.5px;
  line-height: 1.3;
  color: var(--ink);
  overflow: hidden;
}

.wk-block.done .b-name {
  color: var(--read);
  text-decoration: line-through;
}

.wk-block.is-dragging { opacity: .4; }

/* A time was given; a length was not. Drawn at the minimum height so it is
   still something you can see and hit, with an open bottom edge rather than a
   closed one — the block does not know when it ends, and should not claim to. */
.wk-block.no-len {
  border-bottom: 1px dashed var(--tint);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

/* --- resize grips --------------------------------------------------------- */

/* A band along each edge of a block. Invisible until the block is hovered, so a
   block still reads as a thing rather than as a set of controls. */
.wk-grip {
  position: absolute;
  left: 0;
  right: 0;
  height: 7px;
  z-index: 2;
  cursor: ns-resize;
}

.wk-grip.is-top { top: 0; }
.wk-grip.is-bottom { bottom: 0; }

.wk-grip::after {
  content: "";
  position: absolute;
  left: 7px;
  right: 7px;
  top: 50%;
  height: 2px;
  margin-top: -1px;
  border-radius: 2px;
  background: var(--tint);
  opacity: 0;
  transition: opacity .13s ease;
}

.wk-block:hover .wk-grip::after { opacity: .45; }
.wk-grip:hover::after { opacity: 1; }

/* --- now, and the drop indicator ------------------------------------------ */

.wk-now {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  transform: translateY(-50%);
  pointer-events: none;
}

.wk-now .pip {
  width: 7px;
  height: 7px;
  margin-left: -3.5px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 2px var(--sticky);
}

.wk-now .rule {
  flex: 1;
  height: 1.5px;
  background: var(--accent);
  opacity: .6;
}

/* The span being dragged out. Shaped like the block it is about to become, so
   what you are drawing and what you will get are the same rectangle. */
/* Above the blocks and the now-line, below the frozen headings — a column is
   not a stacking context, so these all sort against each other directly. */
.wk-draft {
  position: absolute;
  left: 3px;
  right: 3px;
  z-index: 4;
  overflow: hidden;
  padding: 2px 7px;
  border-radius: 7px;
  background: var(--accent-bg);
  box-shadow: inset 0 0 0 1.5px var(--accent);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 9.5px;
  font-weight: 700;
  line-height: 1.35;
  white-space: nowrap;
  color: var(--accent-ink);
  pointer-events: none;
}

.wk-draft[hidden] { display: none; }

/* Where the task would land, updated as the pointer travels down the column. */
.wk-ghost {
  position: absolute;
  left: 3px;
  right: 3px;
  z-index: 4;
  height: 16px;
  margin-top: -1px;
  padding-left: 5px;
  border-top: 2px solid var(--accent);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 9.5px;
  font-weight: 700;
  color: var(--accent);
  pointer-events: none;
}

/* --- month ---------------------------------------------------------------- */

/* Rows are a fixed height rather than a fraction of the card, because the strip
   is months long and there is no "six rows to fill" any more — how many you see
   is however many fit. It also makes reading the scroll position back out a
   division instead of a measurement. */
.cal-month {
  --mrow: 104px;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-template-rows: auto;
  grid-auto-rows: var(--mrow);
  min-width: 620px;
}

.m-dow {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 7px 0;
  text-align: center;
  font-size: 9.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--faint);
  background: var(--sticky);
  border-bottom: 1px solid var(--hair);
}

.m-cell {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  padding: 4px 5px 5px;
  box-shadow: inset 1px 1px 0 var(--line-2);
  cursor: pointer;
}

/* A strip running through four months has no single month to be "outside" of,
   so months are told apart by banding rather than by dimming every day that is
   not in the current one — which would also mean rebuilding the grid on every
   scroll, just to move the shading. */
.m-cell.is-alt { background-color: var(--fill-2); }

.m-cell:hover { background-color: var(--hover); }

/* A ring, now that the banding owns the background. */
.m-cell.is-sel {
  box-shadow: inset 1px 1px 0 var(--line-2), inset 0 0 0 1.5px var(--ink-2);
}

.m-cell.is-over {
  background-color: var(--accent-bg);
  box-shadow: inset 0 0 0 2px var(--accent);
}

.m-top {
  display: flex;
  align-items: center;
  gap: 5px;
  flex: none;
}

/* A button: the cell around it creates a task, so drilling into the day needs
   its own target. `padding: 0` because a button brings its own. */
.m-num {
  display: grid;
  place-content: center;
  width: 19px;
  height: 19px;
  padding: 0;
  border-radius: 50%;
  font-size: 11.5px;
  color: var(--ink-2);
  cursor: pointer;
}

.m-num:hover { box-shadow: inset 0 0 0 1.5px var(--ink-2); }

.m-cell.is-today .m-num {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}

.m-cell.is-today .m-num:hover { box-shadow: inset 0 0 0 1.5px var(--on-accent); }

/* On the 1st only. In a continuous strip this is the label that says which
   month you have scrolled into, so it carries more weight than it used to. */
.m-mon {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

.m-more {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 9.5px;
  color: var(--faint);
}

.m-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 0;
  overflow: hidden;
}

/* --- pills (month cells and the all-day lane) ----------------------------- */

.m-pill,
.lane-pill {
  display: flex;
  align-items: baseline;
  gap: 5px;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--ink-2);
  background: var(--tint-bg);
  white-space: nowrap;
  overflow: hidden;
  flex: none;
}

.m-pill .p-time,
.lane-pill .p-time {
  flex: none;
  font-size: 9.5px;
  font-weight: 600;
  color: var(--tint);
}

.m-pill .p-name,
.lane-pill .p-name {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Every pill is a task, and every task can be dragged somewhere else. */
.m-pill,
.lane-pill { cursor: grab; }

.m-pill:hover,
.lane-pill:hover { box-shadow: inset 0 0 0 1px var(--tint); }

.m-pill.is-pending,
.lane-pill.is-pending { opacity: .55; cursor: default; }

.m-pill.done,
.lane-pill.done {
  color: var(--read);
  text-decoration: line-through;
}

.m-pill.is-dragging,
.lane-pill.is-dragging { opacity: .4; }
