/* ==========================================================================
   Tasks — the one application sheet, loaded after the brand's main.css.

   Everything the brand does not provide, or provides differently, lives
   here and nowhere else. Each block says which of the two it is: an
   ADDITION the brand has no class for, or an OVERRIDE of a brand rule. An
   override is a candidate for going back into the brand; an addition is a
   candidate for a new brand component. Neither is edited into the brand
   files themselves — those are copied byte for byte from the plugin.
   ========================================================================== */

/* ---------- Tokens (ADDITION) ----------
   Row state colours. The brand palette has no amber and no dark red, and
   its dimmed ink (--fg-soft) is too loud for a struck-through row, so these
   are app tokens. Every fill is paired with the ink that stays legible on it. */

:root {
	--gray-faint: #8b98a1;
	--row-overdue: #8f0f26;
	--row-overdue-ink: var(--ghost-white);
	--row-today: #b35c00;
	--row-today-ink: var(--ghost-white);
	--row-upcoming: #0bbf5c;
	--row-upcoming-ink: var(--onyx);
	--row-undated: rgba(11, 191, 92, 0.42);
	--row-undated-ink: var(--ghost-white);
	--row-completed: var(--bg-muted);
	--row-completed-ink: var(--gray-faint);
	--row-selected: var(--bg-inset);
	--row-new: var(--bg-raised);
	--row-new-ink: var(--fg);
	/* How much of a row's state colour is left in delete mode. */
	--row-dimmed: 40%;
	--tick-size: 1.5rem;
	--z-menu: 50;
}

/* ---------- Shell (OVERRIDE) ----------
   The brand's .app-main carries the page gutter itself; here each view is a
   .container that carries its own, so the gutter is dropped from the shell
   to avoid doubling it. */

.app-main {
	padding-inline: 0;
}

/* ---------- Nav on a phone (OVERRIDE) ----------
   At 768px the brand lets the bar wrap and gives .nav__links the full width,
   which suits a row of text links that needs a line of its own. Here the
   links are one icon button, and the full width drops the hamburger onto a
   line under the wordmark. It belongs beside it, on every width. */

@media (max-width: 768px) {
	.nav,
	.nav__inner {
		flex-wrap: nowrap;
	}

	.nav__links {
		width: auto;
		margin-left: auto;
	}
}

/* ---------- Footer (ADDITION) ---------- */

.footer {
	padding-bottom: calc(var(--space-6) + env(safe-area-inset-bottom, 0px));
}

.footer__inner {
	display: flex;
	justify-content: center;
	font-size: var(--text-xs);
	letter-spacing: var(--tracking-title);
}

/* ---------- List (OVERRIDE) ----------
   Sized like a .container but without its gutter, so a row spans the full
   screen on a phone and the container on a desktop. A row's background is
   what states its status, and leaving the page colour down both sides would
   turn that into a stripe instead of a row. The rows carry the gutter. */

.list {
	max-width: var(--container-max);
	margin-inline: auto;
	border-top: 0;
}

/* Roomier than the brand's list: a row is a thumb target on a phone, and
   the tick needs air on both sides to read as a control of its own. */
.list__row {
	align-items: center;
	gap: var(--space-4);
	padding: var(--space-4) var(--container-pad);
}

/* ---------- List head (ADDITION) ----------
   Holds the add row, or the delete toolbar in its place, and keeps it in
   view while the list scrolls. Sticky, not fixed: it stays in the flow, so
   a viewport moving under it on a phone cannot carry it off the screen the
   way it carried the old floating button. It sits under the nav, which is
   sticky too. Opaque, because the add row's fill is translucent and the
   rows scrolling under it must not show through.

   Not the brand's .list__header: that is a small uppercase group label,
   and everything here is meant to read as a row. */

.list__head {
	position: sticky;
	top: var(--nav-height);
	z-index: var(--z-sticky);
	max-width: var(--container-max);
	margin-inline: auto;
	background-color: var(--bg);
}

/* The toolbar's own margins would push the list down when delete mode
   swaps it in, so it takes the row gutter instead. */
.list__head > .toolbar {
	margin: 0;
	padding: var(--space-3) var(--container-pad);
}

/* ---------- Add row (ADDITION) ----------
   The empty row at the head of the list: the next task waiting to be
   written. A row in shape, with a plus where a task has its tick. */

.list__row--new {
	--row-bg: var(--row-new);
	--row-ink: var(--row-new-ink);
}

/* The brand's ring sits outside the element, and this row runs to the
   edge of a phone screen, so the ring is drawn inside it. */
.list__row--new:focus-visible {
	outline-offset: calc(0px - var(--focus-width));
}

.list__mark {
	flex: 0 0 auto;
	width: var(--tick-size);
	height: var(--tick-size);
	display: grid;
	place-content: center;
}

.list__mark svg {
	width: var(--tick-size);
	height: var(--tick-size);
	fill: none;
	stroke: currentColor;
	stroke-width: 2.5;
}

/* ---------- Selected row (ADDITION) ----------
   Delete mode marks a chosen row with an inset bar in the row's own ink, so
   the mark survives every state colour instead of fighting one of them. */

.list__row.is-selected {
	box-shadow: inset var(--space-1) 0 0 currentColor;
}

/* ---------- Tick (ADDITION) ----------
   The brand styles a switch but not a checkbox, and the browser's stock box
   ignores the row's ink. Drawn here in currentColor so it stays legible on
   every row background. Still an <input type="checkbox"> underneath: the
   label, keyboard and the brand's :focus-visible ring all keep working. */

.tick {
	appearance: none;
	flex: 0 0 auto;
	width: var(--tick-size);
	height: var(--tick-size);
	margin: 0;
	border: 2px solid currentColor;
	border-radius: var(--radius-sm);
	background: transparent;
	cursor: pointer;
	display: grid;
	place-content: center;
}

.tick::before {
	content: '';
	width: 0.45em;
	height: 0.8em;
	border: solid currentColor;
	border-width: 0 3px 3px 0;
	transform: rotate(45deg) scale(0);
	transform-origin: center;
	transition: transform var(--transition);
}

.tick:checked::before {
	transform: rotate(45deg) translate(-1px, -2px) scale(1);
}

/* Also the row's own control — clicking the name opens the task. Styled to
   disappear as a button so the row still reads as a line of text. */
button.list__primary {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0;
	background: none;
	border: 0;
	color: inherit;
	font-weight: inherit;
	text-align: left;
	cursor: pointer;
}

/* ---------- Drag handle (ADDITION) ----------
   The brand has no grip. Six dots in currentColor, like the tick, so it
   reads on every row colour. `touch-action: none` is what makes a finger on
   it drag the row instead of scrolling the page — without it Android takes
   the gesture and fires pointercancel. */

.list__handle {
	flex: 0 0 auto;
	padding: var(--space-2);
	background: none;
	border: 0;
	color: inherit;
	cursor: grab;
	touch-action: none;
	display: grid;
	place-content: center;
}

.list__handle:active {
	cursor: grabbing;
}

.list__handle svg {
	width: 1.25rem;
	height: 1.25rem;
	fill: currentColor;
	opacity: 0.7;
}

/* ---------- Drag state (ADDITION) ----------
   The row being moved is dimmed in place — it is still where it was until
   the drop — and the slot it will land in is a line on the edge of the row
   it will sit beside, in the page ink so it shows on every state colour. */

.list__row.is-dragging {
	opacity: 0.5;
}

.list__row.is-drop-before {
	box-shadow: inset 0 3px 0 0 var(--fg);
}

.list__row.is-drop-after {
	box-shadow: inset 0 -3px 0 0 var(--fg);
}

/* ---------- List row states (ADDITION) ----------
   State by colour, because the row carries no badge to say it. Each state
   only names its pair; one rule below paints. That indirection is what lets
   delete mode fade every state with a single rule instead of five. */

.list__row--overdue {
	--row-bg: var(--row-overdue);
	--row-ink: var(--row-overdue-ink);
}

.list__row--today {
	--row-bg: var(--row-today);
	--row-ink: var(--row-today-ink);
}

.list__row--upcoming {
	--row-bg: var(--row-upcoming);
	--row-ink: var(--row-upcoming-ink);
}

.list__row--undated {
	--row-bg: var(--row-undated);
	--row-ink: var(--row-undated-ink);
}

.list__row--completed {
	--row-bg: var(--row-completed);
	--row-ink: var(--row-completed-ink);
}

.list__row[class*='list__row--'] {
	background-color: var(--row-bg);
	color: var(--row-ink);
}

/* Struck through and dimmed, so a finished task is something the eye skips
   on the way past rather than a line it has to read to dismiss. The brand
   has .is-done for this; the app derives the state name from the record. */
.list__row--completed .list__primary {
	text-decoration: line-through;
}

/* ---------- Delete mode (ADDITION) ----------
   The mode asks one question — which of these go — and the state colours
   are only context for it. They fade rather than vanish: a row still says
   when it is due, quietly enough that the grey of a selected row stands out
   against it. The inset bar from .is-selected stays, but it is a detail at
   the edge of a row; on a screen of full colour it was doing all the work on
   its own and losing.

   The ink goes to the page foreground for every state: Upcoming's dark ink
   was chosen for a solid green and disappears on a faded one. A browser
   without color-mix() drops the declaration and keeps the full colour. */

.list.is-delete-mode .list__row[class*='list__row--'] {
	background-color: color-mix(in srgb, var(--row-bg) var(--row-dimmed), transparent);
	color: var(--fg);
}

.list.is-delete-mode .list__row[class*='list__row--'].is-selected {
	background-color: var(--row-selected);
}

/* The tick is disabled here, and a disabled control is not a hit target —
   the click would die on it instead of reaching the row. Taken out of
   hit-testing altogether, so the row underneath answers for it. */
.list.is-delete-mode .tick {
	pointer-events: none;
	opacity: 0.5;
}

/* ---------- Overdue mark (ADDITION) ----------
   Overdue is never signalled by colour alone — the row also carries a text
   label. This just makes it findable at a glance for those who can see it. */

.is-overdue {
	color: var(--error);
}

/* ---------- Plain icon button (ADDITION) ----------
   .btn--icon boxes its glyph in a grey outline. The hamburger is a glyph in
   the nav, not a boxed control, so this strips the box and keeps the target. */

.btn--plain {
	border-color: transparent;
	background-color: transparent;
}

.btn--plain:hover {
	border-color: transparent;
	background-color: var(--bg-raised);
}

/* ---------- Toolbar count (ADDITION) ----------
   Delete mode's toolbar leads with how many rows are chosen. Set as a label,
   and it takes the free width so the two buttons stay at the right edge. */

.toolbar__count {
	flex: 1 1 auto;
	font-family: var(--font-title);
	font-size: var(--text-sm);
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
}

/* ---------- Menu (ADDITION) ----------
   The nav's one button opens this: a dropdown under the bar, backdrop
   closes it. The brand has no menu component. */

.menu {
	position: fixed;
	inset: 0;
	z-index: var(--z-menu);
	display: flex;
	justify-content: flex-end;
	align-items: flex-start;
	padding-block: var(--nav-height) var(--space-4);
	/* The overlay covers the viewport, but the hamburger that opened it sits
	   at the container's edge, not the window's. On a wide screen a panel at
	   the window edge appears a long way from the button. The same gutter the
	   container gets, so the panel lands under the button on every width. */
	padding-inline: max(
		var(--space-4),
		calc((100% - var(--container-max)) / 2 + var(--container-pad))
	);
	background-color: var(--overlay);
}

.menu__panel {
	display: flex;
	flex-direction: column;
	width: 100%;
	max-width: 260px;
	padding: var(--space-2);
}

.menu__item {
	padding: var(--space-3) var(--space-4);
	background: none;
	border: 0;
	border-radius: var(--radius-sm);
	color: var(--fg);
	font-family: var(--font-title);
	font-size: 0.9rem;
	font-weight: 500;
	letter-spacing: var(--tracking-label);
	text-align: left;
	text-transform: uppercase;
	transition: background-color var(--transition);
}

.menu__item:hover {
	background-color: var(--bg-hover);
}

/* ---------- Confirm dialog actions (OVERRIDE) ----------
   The brand throws `.btn--danger` to the far left of an action row, which is right
   when danger is a third, incidental button next to a separate go button — the task
   form. In the confirm dialog the danger button *is* the go button, so the brand rule
   lands the destructive action on the left and Cancel on the right, backwards from
   every other action row in the app. Scoped to `:last-child` so a dialog that ever
   does carry a tertiary danger button still gets the brand behaviour.
   Candidate to push back into the brand as the general rule. */
.modal__actions .btn--danger:last-child {
	margin-right: 0;
}

/* ---------- Pending badge (ADDITION) ----------
   The brand has .badge--accent/success/error/info, none of which fit. Not a
   warning: the change is saved — this says only that the server has not been
   told yet, which is why the same task may look different elsewhere for now.
   Amber rather than fuchsia, because nothing is wrong. */
.badge--pending {
	border-color: var(--row-today);
	color: var(--row-today);
}
