/* ============================================================================
   CALENDAR — /calendar/
   ============================================================================
   The full-screen year calendar. Its own stylesheet, loaded by its own layout
   (CalendarLayout.astro) after 01-reset and 02-tokens and nothing else, so no
   site rule reaches it and no change here reaches the site.

   It is a separate system on purpose, and it breaks two of the site's rules
   on purpose, with Tom's sign-off (October 2026):

     - IT DECLARES ITS OWN TYPE. 04-typography isn't loaded; the calendar has a
       closed set of its own voices (header, year, month name, weekday, date,
       today, backdrop numeral, wordmark), all declared in the TYPE section
       below and nowhere else in this file. Sizes still come from --step-*.
     - IT FADES INK ON RED. The site has no opacity ramp on red because white
       on red-600 has only 4.99:1 to spend. This field is red-700 (5.83:1), and
       spends it deliberately: weekday letters at 87% white (4.6:1, clears
       4.5); days belonging to the neighbouring month at 40% (1.8:1 — a
       documented exception: they repeat dates shown at full ink in their own
       month, and are aria-hidden); the header weekday in dark ink at 70%
       (2.3:1 — header size, by decision). See the recipe below.

   LAYOUT — the page is one screen. Header, year, footer are rows of a grid
   at least 100dvh tall, and the year takes whatever height is left:

     - landscape viewport → 4 × 3 months
     - portrait viewport  → 3 × 4 months
     - phone portrait     → 2 × 6, and the page scrolls (too narrow for 3)

   The shape is read from the viewport, not from the year's own box. A size
   container on the year was tried first, and it is the more precise answer —
   the header and footer take height the viewport doesn't know about — but
   size containment means the box can't grow to fit its content, so on any
   screen a little too short for the type the months ran into each other.
   Without it the grid only ever *stretches*: when the type fits, the rows
   share out the spare height; when it doesn't, the page grows a scroll and
   nothing overlaps. Short landscape phones fall out of that for free.

   Inside a month, the seven columns hug their widest date and the free space
   goes *between* them (space-between), so the left edge of the M column, the
   left edge of every date under it and the month name are one line, and the
   right edge of the S column is the month's right edge. The rows share out
   the height the same way, which is how the year fills any screen with no
   type-size media query.
   ============================================================================ */


/* ── Recipe ────────────────────────────────────────────────────────────────── */

@layer tokens {

.calendarPage {
	color-scheme: dark;

	/* Built from semantics, as every component recipe is. When the calendar
	   grows themes, a theme is a class that re-points these and nothing else. */
	--cal-surface:      var(--color-surface-brand-deep);
	--cal-ink:          var(--color-on-brand);
	--cal-ink-label:    color-mix(in srgb, var(--color-on-brand) 87%, transparent);
	--cal-ink-adjacent: color-mix(in srgb, var(--color-on-brand) 40%, transparent);
	--cal-ink-dark:     color-mix(in srgb, var(--color-ink-on-brand) 70%, transparent);
	--cal-backdrop:     color-mix(in srgb, var(--color-ink-on-brand) 30%, transparent);
	--cal-today-fill:   var(--color-on-brand);
	--cal-today-ink:    var(--color-ink-on-brand);

	/* Space. The site's --space-* scale, with its ceiling taken off.

	   02-tokens' scale is a clamp() that stops growing at 1240px, which is
	   right for pages read at a desk and wrong for this one: the calendar is
	   meant to fill whatever it's put on, and on a 2560px or 4K screen gaps
	   that stopped at 1240 leave twelve months running together.

	   So each step is max(the site's step, a line through that step's ceiling
	   that keeps going). Below 1240 it is exactly --space-*; past it, every
	   gap grows in proportion to the screen — twice the screen, twice the gap.
	   Nothing caps it.

	   The line passes through each step's ceiling at 1440 × 810, the frame the
	   design was drawn at, so the calendar is exactly the design there and
	   opens up from it. (Anchored at 1240, where the site scale caps, it
	   already ran 16% over the design at 1440 and a 1440-wide laptop window
	   scrolled.) Between 1240 and 1440 the site's ceiling holds.

	   It is the smaller of a width line and a height line. Height matters here
	   because the page is one screen tall: growing on width alone, a 1440 ×
	   810 window gained more gap than it has height and started to scroll.
	   Taking the smaller of the two means a screen only opens up in the
	   direction it actually has room.

	   Type does NOT do this. --step-* still caps at 1240, by decision: the
	   type holds its size and the extra screen goes into air between it.

	   Coefficients: ceiling ÷ 14.4 for vw, ceiling ÷ 8.1 for vh. */
	--cal-space-3xs: max(var(--space-3xs), min(0.3472vw, 0.6173vh));
	--cal-space-2xs: max(var(--space-2xs), min(0.6944vw, 1.2346vh));
	--cal-space-xs:  max(var(--space-xs), min(1.0417vw, 1.8519vh));
	--cal-space-s:   max(var(--space-s), min(1.3889vw, 2.4691vh));
	--cal-space-m:   max(var(--space-m), min(2.0833vw, 3.7037vh));
	--cal-space-l:   max(var(--space-l), min(2.7778vw, 4.9383vh));
	--cal-space-xl:  max(var(--space-xl), min(4.1667vw, 7.4074vh));
	--cal-space-2xl: max(var(--space-2xl), min(5.5556vw, 9.8765vh));

	/* One-up pairs. Below 1240 these are the site's pairs; past it they grow
	   from the larger step's ceiling. */
	--cal-space-xs-s: max(var(--space-xs-s), min(1.3889vw, 2.4691vh));
	--cal-space-s-m:  max(var(--space-s-m), min(2.0833vw, 3.7037vh));
	--cal-space-m-l:  max(var(--space-m-l), min(2.7778vw, 4.9383vh));
	--cal-space-l-xl: max(var(--space-l-xl), min(4.1667vw, 7.4074vh));

	/* Rhythm. The design's spacing at 1440, opening up beyond it. Roughly, on
	   a 16:9 screen (360 / 1440 / 2560px wide):
	     margin      24 / 60 / 107
	     band gap    18 / 30 /  53
	     month gap   24 / 40 /  71
	     row gap     18 / 30 /  53
	     name gap     9 / 15 /  27 */
	--cal-margin:     var(--cal-space-l-xl);
	--cal-band-gap:   var(--cal-space-m);   /* header → year, year → footer */
	--cal-month-gap:  var(--cal-space-l);   /* between month columns */
	--cal-row-gap:    var(--cal-space-m);   /* between month rows */
	--cal-name-gap:   var(--cal-space-xs);  /* month name → its grid */
	/* The least the weeks may close up to. Capped, deliberately: it is a
	   floor for screens with no height to spare, never the gap anyone sees
	   on a screen that fits (space-between does that), and growing it only
	   spends height a short window doesn't have. */
	--cal-week-gap:   var(--space-3xs);
}

} /* @layer tokens */


@layer base {

.calendarPage {
	*, *::before, *::after { box-sizing: border-box; }

	background: var(--cal-surface);
	color: var(--cal-ink);
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;

	:focus-visible {
		outline: 2px solid var(--cal-ink);
		outline-offset: 4px;
	}
}

} /* @layer base */


/* ── Type ──────────────────────────────────────────────────────────────────
   The calendar's closed set. Every font property in this file is here. */

@layer components {

.calendarPage {
	font-family: var(--font);
	font-weight: 400;
	line-height: 1;
	font-variant-numeric: tabular-nums;
}

/* Header: weekday, date and year share a voice; the time is a step down. */
.calNowWeekday,
.calNowDay,
.calYear {
	font-size: var(--step-2);
	font-weight: 500;
}

.calNowTime {
	font-size: var(--step-1);
}

.calMonthName {
	font-size: var(--step-1);
}

.calDow {
	font-size: var(--step-0);
	font-weight: 500;
}

.calDay {
	font-size: var(--step-0);

	&.isToday { font-weight: 700; }
}

/* Sized off the month it sits in, not the viewport — the numeral is a
   proportion of the grid behind it (216px on a 305px month in the design). */
.calBackdrop {
	font-family: var(--font-narrow);
	font-weight: 700;
	font-size: 71cqi;
	line-height: 1;
}

.calMark {
	font-weight: 700;
	font-size: var(--step-1);
	text-transform: uppercase;
	letter-spacing: var(--letter-spacing-loose);
}

} /* @layer components */


/* ── Layout ────────────────────────────────────────────────────────────────── */

@layer components {

.calendar {
	display: grid;
	grid-template-rows: auto 1fr auto;
	gap: var(--cal-band-gap);
	min-height: 100dvh;

	/* Full-screen on every edge: installed, the field runs under the status
	   bar and round the notch, so each margin clears its safe area. */
	padding:
		max(var(--cal-margin), env(safe-area-inset-top, 0px))
		max(var(--cal-margin), env(safe-area-inset-right, 0px))
		max(var(--cal-margin), env(safe-area-inset-bottom, 0px))
		max(var(--cal-margin), env(safe-area-inset-left, 0px));
}

/* --- Header --------------------------------------------------------------- */

.calHeader {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--cal-space-m);
}

.calNow {
	display: flex;
	align-items: baseline;
	gap: 0.5em;
}

.calNowDate {
	display: flex;
	align-items: baseline;
	gap: 0.5em;
}

.calNowWeekday { color: var(--cal-ink-dark); }

/* --- Body: the year ------------------------------------------------------- */

.calBody {
	display: grid;
}

/* Square counts as landscape: once the header and footer are taken out, a
   square screen leaves a wide year. */
.calYearGrid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	grid-auto-rows: 1fr;
	gap: var(--cal-row-gap) var(--cal-month-gap);
}

@media (aspect-ratio < 1) {
	.calYearGrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

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

.calMonth {
	display: grid;
	grid-template-rows: auto 1fr;
	gap: var(--cal-name-gap);
	min-width: 0;
}

.calMonthGrid {
	/* The backdrop numeral is sized in this box's cqi. */
	container-type: inline-size;
	position: relative;

	display: grid;
	grid-template-columns: repeat(7, auto);
	grid-template-rows: repeat(7, auto);
	justify-content: space-between;
	align-content: space-between;
	justify-items: center;
	align-items: center;
	/* The floor, for when the rows have no height to share. On a screen that
	   fits, space-between does the spacing. */
	row-gap: var(--cal-week-gap);
}

.calDow { color: var(--cal-ink-label); }

.calDay {
	position: relative;
	/* Paints above the backdrop numeral, which comes first in the grid. */
	z-index: 1;

	&.isAdjacent { color: var(--cal-ink-adjacent); }

	&.isToday {
		color: var(--cal-today-ink);

		&::before {
			content: "";
			position: absolute;
			z-index: -1;
			inset: 50% auto auto 50%;
			translate: -50% -50%;
			inline-size: 2.15em;
			aspect-ratio: 1;
			border-radius: 50%;
			background: var(--cal-today-fill);
		}
	}
}

/* Today's date, very large, behind its month: centred on the grid, its
   baseline on the grid's last row. Written by calendar.js into the current
   month only. */
.calBackdrop {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	text-align: center;
	color: var(--cal-backdrop);
	pointer-events: none;
	user-select: none;
	/* Trim the line box to the cap height so `bottom: 0` puts the figures'
	   baseline on the grid's edge, not the descender space below it. */
	text-box: trim-both cap alphabetic;
}

@supports not (text-box: trim-both cap alphabetic) {
	.calBackdrop {
		line-height: 0.72;
		bottom: -0.02em;
	}
}

/* --- Footer: the bar and the mark ----------------------------------------- */

.calFooter {
	display: flex;
}

.calMark {
	flex: 1;
	display: flex;
	align-items: center;
	gap: 0.5em;
	color: var(--cal-ink);
	text-decoration-line: none;

	/* The bar is the mark's own block from the site nav, stretched to the
	   width of the page. One cap tall, so it lines up with the letters. */
	&::before {
		content: "";
		flex: 1;
		block-size: 1cap;
		background: currentColor;
	}

	/* The trailing track, cancelled — same optical alignment as .wordmark. */
	margin-inline-end: calc(-1 * var(--letter-spacing-loose));
}

/* --- Phone portrait ------------------------------------------------------ */

/* Three months across leaves a date column about 15px wide. Two across, and
   the year scrolls. */
@media (max-width: 479px) {
	.calYearGrid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		row-gap: var(--cal-space-l);
	}
	.calMonthGrid { row-gap: var(--cal-space-2xs); }
}

} /* @layer components */
