/* Tour schedule shortcode: one column of cards per day, a day picker on narrow screens. */ .schedule { --schedule-line: color-mix(in oklch, var(--color-text) 20%, transparent); --schedule-card-bg: color-mix(in oklch, var(--color-text) 4%, transparent); --schedule-accent: var(--color-link); container-type: inline-size; margin-block: var(--spacing-l); } .schedule__days { display: grid; gap: var(--spacing-l); } /* Hour lines are only drawn in the aligned grid below. */ .schedule__hour { display: none; } /* One column per day; the shortcode puts each card in the row of its start time (--schedule-row), and the subgrids line those rows up across the days. */ @container (width >= 48rem) { .schedule__days { grid-template-columns: repeat(var(--schedule-days), minmax(0, 1fr)); grid-template-rows: auto repeat(var(--schedule-rows), auto); gap: 0.5rem 1rem; } /* Placed explicitly: auto-placement would move the days out of the way of the hour lines. */ .schedule__day { display: grid; grid-column: var(--schedule-column); grid-row: 1 / -1; grid-template-rows: subgrid; } .schedule__list { grid-row: 2 / -1; grid-template-rows: subgrid; } .schedule__card { grid-row: var(--schedule-row); } /* Titles always take two lines, so all cards in the grid are the same size; longer titles get an ellipsis. */ .schedule__title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; min-height: calc(2 * 1.3em); } /* Line above each hour, drawn in the middle of the row gap. Spans all days, so it must not catch clicks meant for the cards. */ .schedule__hour { display: block; grid-column: 1 / -1; grid-row: var(--schedule-row); margin-block-start: -0.25rem; border-block-start: 1px solid var(--schedule-line); pointer-events: none; } } /* Lined up with the time on the cards. */ .schedule__hour-label { display: block; padding: calc(0.5rem + 0.25rem) 0.75rem 0.5rem calc(0.75rem + 3px); font-family: var(--ff-alt); font-size: var(--fs-s); font-weight: bold; font-variant-numeric: tabular-nums; color: var(--color-text-meta); opacity: 0.45; } .schedule__day-title { margin: 0 0 0.75rem; padding-block-end: 0.35rem; border-block-end: 2px solid var(--schedule-accent); font-size: var(--fs-l); } .schedule__date { font-family: var(--ff-alt); font-size: var(--fs-s); font-weight: normal; color: var(--color-text-meta); white-space: nowrap; } .schedule__list { display: grid; gap: 0.5rem; margin: 0; padding: 0; list-style: none; } .schedule__card { position: relative; display: grid; grid-template-columns: 1fr auto; gap: 0.15rem 0.5rem; margin: 0; padding: 0.5rem 0.75rem 0.6rem; border: 1px solid var(--schedule-line); border-inline-start: 3px solid var(--schedule-accent); border-radius: var(--radius-m); background: var(--schedule-card-bg); transition: border-color 0.15s; &:hover { border-color: var(--schedule-accent); } &:has(a:focus-visible) { outline: 2px solid var(--schedule-accent); outline-offset: 2px; } } .schedule__when { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.5rem; } .schedule__status { font-family: var(--ff-alt); font-size: var(--fs-xs); font-weight: bold; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-text-meta); } /* Fully booked: still listed and linked, but muted. */ .schedule__card--soldout { border-inline-start-color: var(--schedule-line); & .schedule__title { color: var(--color-text-meta); } } .schedule__time { font-family: var(--ff-alt); font-size: var(--fs-s); font-weight: bold; font-variant-numeric: tabular-nums; color: var(--color-text-meta); } .schedule__langs { /* Above the card-wide link, so the badge tooltip still works. */ position: relative; z-index: 1; display: flex; gap: 0.25rem; } .schedule__lang { padding: 0 0.4rem; border: 1px solid var(--schedule-line); border-radius: 999px; font-family: var(--ff-alt); font-size: var(--fs-xs); letter-spacing: 0.03em; text-decoration: none; color: var(--color-text-meta); cursor: help; } .schedule__title { grid-column: 1 / -1; font-family: var(--ff-headings); font-weight: 600; line-height: 1.3; text-decoration: none; /* Make the whole card clickable. Being absolutely positioned against the card, it is not clipped by the overflow set in the grid view. */ &::after { content: ""; position: absolute; inset: 0; border-radius: inherit; } } /* The picker only exists with JavaScript and is only used on narrow screens. */ .schedule__picker { display: none; } @container (width < 48rem) { .schedule__picker:not([hidden]) { position: sticky; inset-block-start: 0; z-index: 2; display: flex; gap: 0.25rem; margin-block-end: 1rem; padding: 0.25rem; border-radius: var(--radius-l); background: var(--color-body-bg); box-shadow: inset 0 0 0 1px var(--schedule-line); } .schedule__pick { flex: 1; display: flex; flex-direction: column; align-items: center; padding: 0.35rem 0.25rem; border: 0; border-radius: var(--radius-m); background: transparent; color: var(--color-text); font-family: var(--ff-alt); font-size: var(--fs-s); font-weight: bold; cursor: pointer; &[aria-pressed="true"] { background: var(--schedule-accent); color: var(--color-body-bg); .schedule__pick-date { color: inherit; } } } .schedule__pick-date { font-size: var(--fs-xs); font-weight: normal; color: var(--color-text-meta); } .schedule--picker { .schedule__day:not(.schedule__day--selected) { display: none; } /* The picker already names the day. */ .schedule__day-title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } } }