/**
 * WP Group Scheduler — frontend styles.
 *
 * All colors are CSS custom properties (--wgs-*) rather than hardcoded
 * hex values, specifically so Phase 9's dark mode can override them by
 * setting a `data-theme="dark"` attribute higher up the DOM without
 * touching this file again. Defaults defined here are the LIGHT values;
 * Phase 9 adds a `[data-theme="dark"]` block (in its own theme-dark.css)
 * that redefines the same variable names.
 */

.wgs-survey,
.wgs-frontend-wrap {
	/* These are the DARK values, used as the base/default — i.e. what
	   applies even before assets/js/theme-toggle.js runs and sets a
	   data-theme attribute. The plan is explicit that "the effective
	   default before any JS runs" must be dark, not light, so there's no
	   flash of light-mode content on first paint. theme-light.css then
	   provides the [data-theme="light"] override for anyone who actually
	   wants light mode (whether via their own preference or a site admin
	   who set the default to light) — theme-dark.css's [data-theme="dark"]
	   block ends up being redundant with these base values in practice,
	   but is kept for explicitness/symmetry with theme-light.css rather
	   than relying on "absence of an override" to mean dark, matching the
	   same reasoning theme-light.css's own header comment gives for why
	   it exists as an explicit file rather than an implicit default. */
	--wgs-bg: #1e1e1e;
	--wgs-text: #e8e8e8;
	--wgs-border: #3a3a3a;
	--wgs-muted: #a0a0a0;

	--wgs-cell-unselected: #333333;
	--wgs-cell-unselected-text: #cccccc;
	--wgs-cell-very-likely: #2ea043;
	--wgs-cell-very-likely-text: #0d1f10;
	--wgs-cell-potentially: #d29922;
	--wgs-cell-potentially-text: #241b02;
	--wgs-cell-not-available: #e5534b;
	--wgs-cell-not-available-text: #240a08;

	--wgs-heat-low: #333333;
	--wgs-heat-high: #4a9eff;

	color: var( --wgs-text );
	background: var( --wgs-bg );

	/* Fix: the plugin previously left width entirely up to whatever
	   container it happened to be rendered inside — the shortcode/
	   permalink output is just a plain <div>, and most themes wrap
	   post/page content (.entry-content and similar) in a container
	   with its own max-width, so the grid ended up squeezed into a
	   narrow column with empty space on both sides regardless of how
	   wide the actual screen was.
	   The actual full-width "breakout" (making this element span the
	   real browser viewport regardless of how its ancestors are laid
	   out) is done in assets/js/layout.js, not here. An earlier version
	   of this fix tried a pure-CSS `left: 50%; margin-left: -50vw`
	   trick, but that formula only cancels out correctly when every
	   ancestor is perfectly horizontally centered on the viewport —
	   on a theme with a sidebar, asymmetric padding, or a non-centered
	   layout, the two offsets don't cancel and the element ends up
	   shifted to one side with unwanted horizontal scroll. Measuring
	   each ancestor's actual rendered offset in JS and cancelling it
	   exactly works regardless of the theme's layout, so that's what's
	   used instead — this rule now only supplies the padding so
	   content doesn't touch the physical screen edges once JS has
	   done the width/margin adjustment. */
	box-sizing: border-box;
	padding-left: clamp( 16px, 4vw, 56px );
	padding-right: clamp( 16px, 4vw, 56px );
}

.wgs-notice {
	background: var( --wgs-cell-unselected, #f8f8f8 );
	border-left: 4px solid var( --wgs-muted, #999 );
	padding: 0.8em 1.2em;
}

.wgs-survey__header {
	margin-bottom: 1em;
}

.wgs-survey__closed-notice {
	background: var( --wgs-cell-potentially );
	color: var( --wgs-cell-potentially-text );
	padding: 0.6em 1em;
	margin-bottom: 1em;
	border-radius: 3px;
}

.wgs-grid-form__identity {
	margin-bottom: 1em;
}

.wgs-grid-form__name-label {
	display: block;
	font-weight: 600;
	margin-bottom: 0.3em;
}

.wgs-grid__legend {
	display: flex;
	flex-wrap: wrap;
	gap: 1em;
	margin-bottom: 0.8em;
	font-size: 0.9em;
}

.wgs-legend-item {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
}

.wgs-cell-swatch {
	display: inline-block;
	width: 1em;
	height: 1em;
	border-radius: 2px;
}

/* Bugfix: this block used to also carry .wgs-grid__cell--very-likely /
   --potentially / --not-available / --unselected background rules
   alongside these .wgs-cell-swatch--* ones (same selector list, since the
   legend swatches and the cell states use the same colors). That put the
   cell background rules earlier in the file than the base .wgs-grid__cell
   rule below, which also sets `background` — both selectors have equal
   specificity (one class), so CSS resolves the tie by source order, and
   the base rule (declared later) silently won, overriding the state
   color's background. The matching `color` (text) rules happened to
   already be declared after the base rule, which is why only text color
   reliably changed on selection, not the cell background. The
   .wgs-grid__cell--* background+color declarations now live together,
   after the base rule, further down this file — see the block right
   after .wgs-grid__cell's own rule. Do not add .wgs-grid__cell--* back
   here even though the colors are identical; keep this block swatch-only. */
.wgs-cell-swatch--very-likely {
	background: var( --wgs-cell-very-likely );
}

.wgs-cell-swatch--potentially {
	background: var( --wgs-cell-potentially );
}

.wgs-cell-swatch--not-available {
	background: var( --wgs-cell-not-available );
}

.wgs-cell-swatch--unselected {
	background: var( --wgs-cell-unselected );
}

.wgs-grid-toolbar {
	margin-bottom: 0.8em;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5em;
}

.wgs-grid-toolbar__default-selection {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.4em;
}

.wgs-grid-toolbar__default-selection-label {
	font-weight: 600;
	margin-right: 0.2em;
}

/* Task 12 (mobile audit): none of the toolbar's buttons had any sizing of
   their own before this — they were riding on the bare browser-default
   <button> box (no wp-admin buttons.css is enqueued on the frontend; see
   public/class-shortcode.php's enqueue list), which is well under common
   ~44px tap-target guidance. This applies at all widths, not just inside
   the <600px media query below, since a small tap target is just as much
   a problem on a touchscreen tablet above that breakpoint.
   Placed BEFORE the .is-active rule below: both selectors are two classes
   deep (equal specificity), so source order decides ties, and .is-active's
   background/color/border-color override needs to keep winning over this
   rule's background/color, not the other way around. */
.wgs-grid-toolbar .button {
	min-height: 44px;
	min-width: 44px;
	padding: 0.5em 1em;
	line-height: 1.2;
	font-size: 0.9em;
	border: 1px solid var( --wgs-border );
	border-radius: 4px;
	background: var( --wgs-cell-unselected );
	color: var( --wgs-text );
	cursor: pointer;
}

.wgs-grid-toolbar__default-btn.is-active {
	background: var( --wgs-heat-high, #2271b1 );
	color: #fff;
	border-color: var( --wgs-heat-high, #2271b1 );
}

/* Task 25 (mobile audit): the Task 19 view-switcher buttons
   (`.wgs-grid-view-switcher`, wired in grid.js's
   renderStructureViewSwitcher()) had NO dedicated CSS at all — the
   "Task 12 mobile audit" 44px tap-target fix immediately above only
   ever covered `.wgs-grid-toolbar .button`, a DIFFERENT, separate
   container from the view switcher (see
   public/templates/survey-grid.php's markup), added well before Task
   19's view switcher existed to need covering. Without this, the view-
   switcher buttons were riding on the bare browser-default <button> box
   — same under-44px tap-target gap Task 12's fix originally existed to
   close, just re-opened for a container that fix never anticipated.
   Mirrors that fix's exact values/reasoning (applies at all widths, not
   just <600px, for the same reason a small tap target is just as much a
   problem above that breakpoint on a touchscreen tablet). */
.wgs-grid-view-switcher {
	margin-bottom: 0.8em;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5em;
}

.wgs-grid-view-switcher__btn {
	min-height: 44px;
	min-width: 44px;
	padding: 0.5em 1em;
	line-height: 1.2;
	font-size: 0.9em;
	border: 1px solid var( --wgs-border );
	border-radius: 4px;
	background: var( --wgs-cell-unselected );
	color: var( --wgs-text );
	cursor: pointer;
}

.wgs-grid-view-switcher__btn.is-active {
	background: var( --wgs-heat-high, #2271b1 );
	color: #fff;
	border-color: var( --wgs-heat-high, #2271b1 );
}

/* Bugfix: horizontal scrolling used to live directly on this element,
   but `.wgs-grid-wrapper` is also the direct parent of the pagination
   prev/next buttons (grid.js's renderDenseGrid()/buildPaginationWrap())
   — and `overflow-x: auto` on ANY ancestor of a `position: sticky`
   element breaks that element's stickiness (per the CSS Overflow spec,
   `overflow-x: auto` with the default `overflow-y: visible` computes
   to `overflow-y: auto` too, making this a full scroll container even
   though it never actually needs to scroll vertically). The buttons'
   chevron icons rely on staying sticky to the viewport so they're
   reachable without scrolling on a tall grid (see
   .wgs-grid-page-btn__icon below) — so the actual `overflow-x: auto`
   now lives on `.wgs-grid-page-scroll`, a dedicated inner div around
   just the `<table>`, in BOTH the paginated and non-paginated cases.
   This element stays overflow-free so it's never a scroll container. */
.wgs-grid-wrapper {
	border: 1px solid var( --wgs-border );
	padding: 0.5em;
}

/* Task 10b: only present when columnValues.length >= 11 (grid.js's
   buildPaginationWrap()) — flanks the grid with simple chevron buttons
   rather than the general page toolbar, since paging is a property of
   the grid itself (which columns are visible), not the survey page.

   Bugfix (large surveys): `align-items` used to be `center`, which
   centers each flex item at the MIDDLE of the row's cross-axis size —
   fine while the grid was short, but on a survey with many rows the
   grid (and therefore this row) can end up many screens tall, which
   left the actual clickable button sitting off-screen at the vertical
   midpoint of the whole grid until you scrolled down (or up) to go
   find it. `stretch` (the flex default, restored explicitly here for
   clarity) instead makes each page button's own box match the FULL
   height of its tallest sibling — i.e. the grid itself — turning it
   into a full-height side rail rather than a small centered dot. See
   .wgs-grid-page-btn below for how the button then keeps its chevron
   glyph visible/reachable without requiring the user to scroll to the
   middle of that tall box. */
.wgs-grid-page-wrap {
	display: flex;
	align-items: stretch;
	gap: 0.5em;
}

/* Wraps just the <table>, not the prev/next buttons — see grid.js's
   buildPaginationWrap() docblock for why the overflow-x here has to
   stay scoped this narrowly (it would otherwise break position:sticky
   on the buttons' chevron icons). */
.wgs-grid-page-scroll {
	flex: 1;
	min-width: 0; /* let this shrink inside the flex row instead of overflowing it */
	overflow-x: auto;
}

/* Full-height side rail (stretched via .wgs-grid-page-wrap's
   align-items: stretch above) rather than a small fixed-size circle —
   the whole strip is clickable, not just a dot at the vertical middle,
   so paging works from wherever the visitor happens to have scrolled
   to. Deliberately no `height` set here: an explicit height would
   override the stretch and bring back the old small-button behavior. */
.wgs-grid-page-btn {
	flex: 0 0 auto;
	width: 2.25em;
	min-height: 2.25em; /* floor for very short/unpaginated-height edge cases */
	padding: 0;
	border: 1px solid var( --wgs-border );
	border-radius: 6px;
	background: var( --wgs-cell-unselected );
	color: var( --wgs-text );
	font-size: 1.1em;
	line-height: 1;
	cursor: pointer;
	transition: background-color 0.1s ease, color 0.1s ease, opacity 0.1s ease;
}

.wgs-grid-page-btn:hover:not( :disabled ) {
	background: var( --wgs-heat-high, #4a9eff );
	color: #fff;
}

.wgs-grid-page-btn:focus-visible {
	outline: 2px solid var( --wgs-heat-high );
	outline-offset: 1px;
}

.wgs-grid-page-btn:disabled {
	opacity: 0.35;
	cursor: default;
}

/* The chevron glyph itself (grid.js's makePageBtnIcon()) is a separate
   sticky-positioned child of the now full-height button — this is what
   actually keeps it in view as the page scrolls, clamped to the
   button's own top/bottom bounds so it never drifts outside the grid
   it belongs to. `top` is offset a little below the wrapper's edge
   rather than 0 so the icon doesn't sit flush against the browser
   chrome/any sticky site header when it's stuck. */
.wgs-grid-page-btn__icon {
	position: sticky;
	top: 0.75em;
	display: flex;
	align-items: center;
	justify-content: center;
}

.wgs-grid {
	display: grid;
	grid-template-columns: minmax( 90px, auto ) repeat( var( --wgs-grid-cols, 2 ), minmax( 60px, 1fr ) );
	/* Task 9: bumped from 2px to 4px for a slightly airier look. Checked
	   against the Task 10 "7x7 fits a desktop screen" constraint before
	   changing this: 7 data columns (min 60px) + the row-header column
	   (min 90px) + 7 gaps of 4px = 90 + 420 + 28 = 538px, comfortably
	   inside a 1280px viewport even with the wrapper's own padding/border
	   added on top, so this doesn't threaten that constraint. */
	gap: 4px;
}

/* Task 20: date_scheduler/timeslot_scheduler's flat 'grid' view has no
   row-header column at all (unlike the classic grid's .wgs-grid rule
   above, which always reserves a leading minmax(90px, auto) track for
   one) — this modifier replaces the column template entirely rather than
   adjusting it, so `renderFlatSevenColumnGrid()`'s fixed-at-7-columns
   layout isn't shifted right by a phantom header column. Kept alongside
   the base .wgs-grid class (not applied instead of it) so the existing
   cell/shift/hover/focus CSS that targets .wgs-grid keeps applying here
   unchanged. */
.wgs-grid.wgs-grid--flat {
	grid-template-columns: repeat( 7, minmax( 0, 1fr ) );
}

/* Task 21: the date-scheduler's calendar/year views DO need a
   row-header column (for the ISO week-number cell), but the base
   .wgs-grid rule's minmax(90px, auto) was sized for the classic grid's
   row headers, which hold full dates/times/weekday names — a bare 1-2
   digit week number doesn't need that much width, and reusing it as-is
   would leave a wide, mostly-empty leading column next to normal-width
   day cells. Narrower dedicated leading track instead; still
   auto-sizing if a particular week number needs slightly more room. */
.wgs-grid.wgs-grid--calendar {
	grid-template-columns: minmax( 32px, auto ) repeat( var( --wgs-grid-cols, 7 ), minmax( 60px, 1fr ) );
}

/* Task 21: "you are here" marker for today's cell in the calendar/year
   views, layered on top of whichever of the three day-cell kinds
   today's cell actually is — purely visual, doesn't change click-
   ability. Deliberately `outline` (with a negative offset so it draws
   inward rather than adding to the cell's box size), NOT `border`: a
   border-based marker would collide with .wgs-grid__cell--empty's
   existing `border: none` shorthand rule above — same-specificity rules
   resolve by source order, so a later `border: none` would silently win
   and erase an earlier `border-width` declaration on the same element.
   This is the same class of conflict Task 9's hover state already had
   to route around with box-shadow instead of filter, for an analogous
   reason (see that rule's comment above .wgs-grid__cell:hover). */
.wgs-grid__cell--today {
	outline: 2px solid var( --wgs-heat-high, #4a9eff );
	outline-offset: -2px;
}

/* Task 21: calendar-view container — month/year header with prev/next
   nav flanking a centered title, above the actual day-grid. */
.wgs-calendar-view__header {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.75em;
	margin-bottom: 0.6em;
}

.wgs-calendar-view__title {
	font-weight: 600;
	font-size: 1.1em;
	min-width: 9em;
	text-align: center;
}

/* Same 44px tap-target reasoning as .wgs-grid-toolbar .button above —
   these are real interactive nav buttons, not decorative. */
.wgs-calendar-view__nav {
	min-height: 44px;
	min-width: 44px;
	padding: 0.4em 0.8em;
	font-size: 1.1em;
	line-height: 1;
	border: 1px solid var( --wgs-border );
	border-radius: 4px;
	background: var( --wgs-cell-unselected );
	color: var( --wgs-text );
	cursor: pointer;
}

/* Task 10a: 8-10 columns shrink for THAT RENDER ONLY (grid.js adds this
   class per-render based on columnValues.length, never writes to the
   underlying settings) — scaled via calc() off the existing base
   --wgs-grid-font-size/--wgs-grid-cell-padding custom properties rather
   than duplicating the settings-derived values here, so it stays in sync
   automatically if an admin changes the base font/padding settings later. */
.wgs-grid--compact {
	--wgs-grid-font-size: calc( var( --wgs-grid-font-size, 21px ) * 0.8 );
	--wgs-grid-cell-padding: calc( var( --wgs-grid-cell-padding, 15px ) * 0.8 );
}

/* Task 22: year view — 12 mini-month `.wgs-grid--calendar` tables laid
   out 3-per-row on desktop (4 rows of 3 for a full year; a 4th row
   scrolling into view is expected/fine, per spec only 9 months need to
   fit without scrolling) and 1-per-row, stacked, on mobile — reusing the
   same `(max-width: 600px)` breakpoint constant `renderGrid()`'s
   `mobileQuery` already checks, for consistency with the rest of the
   plugin's responsive behavior. */
.wgs-year-view__grid {
	display: grid;
	grid-template-columns: repeat( 3, 1fr );
	gap: 1.4em 1em;
}

@media ( max-width: 600px ) {
	.wgs-year-view__grid {
		grid-template-columns: 1fr;
	}
}

.wgs-year-view__month-title {
	font-weight: 600;
	font-size: 0.85em;
	text-align: center;
	margin-bottom: 0.3em;
}

/* Task 22: visibly more compact than Task 21's single calendar view —
   both a smaller calc() step than `.wgs-grid--compact`'s 0.8 multiplier
   above (needed to stay legible at 3-per-row desktop width) and narrower
   column tracks than the base `.wgs-grid--calendar` rule (sized for a
   single full-width month, not a third of one). Layered on top of
   `.wgs-grid--calendar` (three classes = higher specificity, so this
   cleanly overrides its grid-template-columns) rather than duplicating
   that rule's --wgs-grid-cols variable/corner-column structure. Reuses
   the same --wgs-grid-font-size/--wgs-grid-cell-padding calc() scaling
   approach as `.wgs-grid--compact` rather than hardcoding a second set
   of magic numbers, so it too stays in sync if an admin changes the base
   font/padding settings. */
.wgs-grid.wgs-grid--calendar.wgs-grid--year-mini {
	grid-template-columns: minmax( 16px, auto ) repeat( var( --wgs-grid-cols, 7 ), minmax( 20px, 1fr ) );
	gap: 2px;
	--wgs-grid-font-size: calc( var( --wgs-grid-font-size, 21px ) * 0.55 );
	--wgs-grid-cell-padding: calc( var( --wgs-grid-cell-padding, 15px ) * 0.55 );
}

.wgs-grid__header {
	/* Bugfix: font-size now derives from the plugin's own
	   --wgs-grid-font-size custom property (the same one .wgs-grid__cell
	   uses below), instead of a bare `em` value relative to whatever
	   font-size the active WordPress theme happens to inherit down to
	   this element. A bare em here meant themes with a larger base/fluid
	   font-size (common with block-theme typography) could render header
	   text well past the 14px the plugin intends, which overflowed the
	   cell and visually bled into the neighboring one. 1.05x keeps
	   headers reading slightly bolder/larger than data cells, matching
	   the original Task 9 intent, but anchored to a value the plugin
	   actually controls.
	   overflow/text-overflow/white-space added so a label that still
	   doesn't fit (e.g. a long weekday name in a narrow column) clips
	   with an ellipsis instead of spilling into the next cell. */
	font-weight: 700;
	font-size: calc( var( --wgs-grid-font-size, 21px ) * 1.05 );
	font-family: var( --wgs-grid-font-family, inherit );
	padding: 0.4em;
	text-align: center;
	background: var( --wgs-cell-unselected );
	cursor: pointer;
	user-select: none;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.wgs-grid__header--corner {
	cursor: default;
	background: transparent;
	/* The corner sits where both the header row and header column meet
	   the data grid, so it gets both separating borders. */
	border-bottom: 2px solid var( --wgs-border );
	border-right: 2px solid var( --wgs-border );
}

.wgs-grid__header--row {
	text-align: right;
	cursor: pointer;
	/* Separates the row-header column from the data grid to its right. */
	border-right: 2px solid var( --wgs-border );
}

.wgs-grid__header--column {
	/* Separates the header row from the data grid below it. */
	border-bottom: 2px solid var( --wgs-border );
}

.wgs-grid__cell {
	/* Task 9 point 3: sizing now derives from the admin-configurable
	   typography/spacing settings (Task 2a) via the CSS custom properties
	   Task 3 computes, instead of a hardcoded min-height. Centered with
	   flex since the cell's only content is a single .wgs-grid__cell-time
	   span (Task 7). */
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var( --wgs-grid-cell-padding, 15px );
	font-size: var( --wgs-grid-font-size, 21px );
	font-family: var( --wgs-grid-font-family, inherit );
	/* Task 9 point 1: small radius, not pill-shaped. */
	border-radius: 5px;
	border: 1px solid var( --wgs-border );
	background: var( --wgs-cell-unselected );
	color: var( --wgs-cell-unselected-text );
	cursor: pointer;
	touch-action: none; /* prevent scroll interfering with drag-select on touch */
	/* Kept quick/non-bouncy per the spec — box-shadow added alongside the
	   existing background-color transition for the new hover state below,
	   not a slower/springier easing. */
	transition: background-color 0.1s ease, box-shadow 0.1s ease;
}

/* Bugfix: on desktop, cells rendered as squares rather than the short,
   wide rectangles that read more cleanly on a landscape screen and give
   each cell's time label more breathing room without wasting vertical
   space. The base rule above uses a single --wgs-grid-cell-padding value
   on all four sides via the `padding` shorthand, so height and width
   ended up coincidentally similar once column width settled near its
   minmax() floor. Placed directly after the base rule (not just anywhere
   in the file) since this uses the same specificity (one class) as that
   rule's own `padding` shorthand — CSS resolves equal-specificity ties by
   source order, so this must come after it to actually win. Mirrors the
   existing "Below ~600px" breakpoint further down with its own opposite-
   direction breakpoint, rather than changing the base rule directly, so
   mobile's existing (already-compact, touch-target-sized) cell shape is
   left untouched. */
@media ( min-width: 601px ) {
	.wgs-grid__cell {
		padding-top: calc( var( --wgs-grid-cell-padding, 15px ) * 0.55 );
		padding-bottom: calc( var( --wgs-grid-cell-padding, 15px ) * 0.55 );
		padding-left: calc( var( --wgs-grid-cell-padding, 15px ) * 1.4 );
		padding-right: calc( var( --wgs-grid-cell-padding, 15px ) * 1.4 );
	}
}

/* Task 9 point 1: subtle hover feedback on clickable cells only (not the
   empty/non-applicable placeholders, which aren't interactive) — a
   box-shadow rather than a filter, deliberately, so it composes cleanly
   with the Task 9 point 4 alternating-shift inline `style.filter` some
   cells carry (an inline style always wins over a stylesheet rule for the
   same property regardless of :hover, so a `:hover { filter: … }` rule
   here would simply never appear on shifted cells; box-shadow sidesteps
   that entirely since it isn't set inline by anything else). No
   transform/scale and no slow transition, so this needs no
   prefers-reduced-motion guard — there's no motion to begin with. */
.wgs-grid__cell:not( .wgs-grid__cell--empty ):hover:not( :disabled ) {
	box-shadow: 0 0 0 2px var( --wgs-heat-high, #4a9eff ) inset;
}

/* Bugfix: background is now declared together with color here (both were
   previously split — background lived earlier in the file alongside the
   legend swatch rules, color lived here — see the comment on
   .wgs-cell-swatch--very-likely etc. above for the full explanation of
   why that split silently dropped the background change). Keeping both
   declarations in the same rule, after the base .wgs-grid__cell rule,
   means there's no cascade-order tie to accidentally lose to a future
   edit either. */
.wgs-grid__cell--very-likely {
	background: var( --wgs-cell-very-likely );
	color: var( --wgs-cell-very-likely-text );
}

.wgs-grid__cell--potentially {
	background: var( --wgs-cell-potentially );
	color: var( --wgs-cell-potentially-text );
}

.wgs-grid__cell--not-available {
	background: var( --wgs-cell-not-available );
	color: var( --wgs-cell-not-available-text );
}

.wgs-grid__cell--unselected {
	background: var( --wgs-cell-unselected );
	color: var( --wgs-cell-unselected-text );
}

/* Task 9 point 4: alternating row/column brightness/hue shifts.
   assets/js/grid.js's renderDenseGrid() adds `wgs-row-even`/`wgs-row-odd`
   and `wgs-col-even`/`wgs-col-odd` classes to each dense-grid data/empty
   cell at creation time (it already knows each cell's row/column index),
   but no CSS rule is defined for those classes here — the actual visual
   shift is computed in JS (reading the --wgs-row-*-shift-mode/-amount and
   --wgs-col-*-shift-mode/-amount custom properties from Task 3) and
   applied as an inline `style.filter` per cell, since plain CSS has no
   way to branch on the shift-mode STRING ("brightness" vs "hue" vs
   "none") the way `var()` fallback chaining can branch on an unset
   property. The classes are still added so a future pass (e.g. the
   mobile-layout audit) has something to select against without needing
   to know JS internals. Do not "simplify" this back into a pure-CSS
   nth-child approach — see grid.js's renderDenseGrid() docblock for the
   fuller explanation, including why plain `nth-child` can't cleanly
   express column parity on a CSS Grid's flat DOM child order in the
   first place. */

.wgs-grid__cell:focus-visible {
	outline: 2px solid var( --wgs-heat-high );
	outline-offset: -2px;
}

.wgs-grid__cell--empty {
	/* Task 9: previously hardcoded transparent; now sourced from the
	   Task 2a "_color_empty"/"_text_empty" admin settings via the Task 3
	   custom properties, so the greyed-out non-applicable cell color is
	   actually configurable like the other cell states are. */
	background: var( --wgs-cell-empty, transparent );
	color: var( --wgs-cell-empty-text, inherit );
	border: none;
	cursor: default;
}

/* Task 7: every data cell shows its own start time as visible text
   (makeDataCell()'s .wgs-grid__cell-time span) — kept small/muted since
   in Option 1 ('timeslot_headers') it's secondary to the shared
   timeslot header, and in Option 2 ('compact_columns') it's the ONLY
   place that time is shown at all. Full typographic treatment is
   Task 9's job; this is just enough to be legible now. */
.wgs-grid__cell-time {
	font-size: 0.75em;
	line-height: 1.2;
	pointer-events: none;
}

/* Task 7: Option 2's unlabeled timeslot-axis spacer header (see
   makeTimeslotAxisHeaderCell()) — visually inert, not a real
   interactive header, so it doesn't get the pointer cursor the other
   header kinds have. */
.wgs-grid__header--spacer {
	cursor: default;
}

.wgs-grid-form__actions {
	margin-top: 1em;
	display: flex;
	align-items: center;
	gap: 1em;
}

.wgs-grid-form__edit-link-notice {
	margin-top: 1em;
	padding: 0.8em 1em;
	background: var( --wgs-cell-unselected );
	border-radius: 3px;
}

.wgs-grid-form__edit-link-input {
	width: 100%;
	margin-top: 0.4em;
}

.wgs-survey__results-anchor,
.wgs-survey__comments-anchor {
	margin-top: 2em;
}

.wgs-frontend-wrap .wgs-form-section {
	background: var( --wgs-bg, #fff );
	border: 1px solid var( --wgs-border, #ddd );
	padding: 1em 1.5em;
	margin-bottom: 1.5em;
}

/* ------------------------------------------------------------------
   Results: shortlist, heatmap, popover.
   Shared between the admin results tab (Phase 5) and the frontend
   survey page (Phase 7b) — see admin-builder.css's note on why this
   moved here instead of staying admin-only.
   ------------------------------------------------------------------ */

/* --wgs-heat-low / --wgs-heat-high are already defined on the
   .wgs-survey / .wgs-frontend-wrap root (top of this file) and inherited
   here via normal CSS custom-property cascade, since .wgs-results always
   renders nested inside one of those roots. Deliberately NOT redeclared
   here — an earlier draft did redeclare them with the same light-mode
   hex values, which looked harmless but would have silently pinned the
   heatmap to light-mode colors even under [data-theme="dark"], since a
   redeclaration always wins over an inherited value regardless of which
   one is "more specific" in a dark-mode sense. */

.wgs-results__finalized-banner {
	background: var( --wgs-cell-very-likely, #edfaef );
	color: var( --wgs-cell-very-likely-text, #1e1e1e );
	border-radius: 3px;
	padding: 0.8em 1.2em;
	margin-bottom: 1em;
}

.wgs-results__legend {
	margin-bottom: 0.5em;
	font-size: 0.9em;
}

.wgs-legend-swatch {
	display: inline-block;
	width: 1em;
	height: 1em;
	vertical-align: middle;
	margin-right: 0.3em;
	border-radius: 2px;
}

.wgs-legend-swatch--low {
	background: var( --wgs-heat-low );
}

.wgs-legend-swatch--high {
	background: var( --wgs-heat-high );
}

.wgs-results__shortlist-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.wgs-results__shortlist-item {
	border: 1px solid var( --wgs-border, #dcdcde );
	border-radius: 4px;
	padding: 0.8em 1em;
	margin-bottom: 0.6em;
}

.wgs-results__shortlist-heading {
	font-weight: 600;
	display: flex;
	align-items: center;
	gap: 0.6em;
}

.wgs-results__shortlist-readout {
	color: var( --wgs-muted, #666 );
	font-size: 0.9em;
	margin-top: 0.2em;
}

.wgs-results__shortlist-names {
	font-size: 0.85em;
	margin-top: 0.4em;
	display: flex;
	flex-direction: column;
	gap: 0.2em;
}

.wgs-badge {
	display: inline-block;
	font-size: 0.75em;
	padding: 0.1em 0.5em;
	border-radius: 10px;
}

.wgs-badge--everyone-free {
	background: var( --wgs-cell-very-likely, #1a8a3d );
	color: var( --wgs-cell-very-likely-text, #fff );
}

.wgs-heatmap {
	display: grid;
	grid-template-columns: minmax( 90px, auto ) repeat( var( --wgs-grid-cols, 2 ), minmax( 50px, 1fr ) );
	gap: 2px;
}

.wgs-heatmap__header {
	/* Bugfix: same fix as .wgs-grid__header above — size off the plugin's
	   own --wgs-grid-font-size custom property (inherited from the
	   .wgs-survey/.wgs-frontend-wrap root this always renders inside)
	   rather than a bare em relative to the ambient theme font-size, and
	   clip overflow instead of letting long labels bleed into the next
	   cell. */
	font-weight: 600;
	font-size: calc( var( --wgs-grid-font-size, 21px ) * 0.85 );
	padding: 0.3em;
	text-align: center;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.wgs-heatmap__cell {
	position: relative;
	min-height: 2.2em;
	border: 1px solid var( --wgs-border, #dcdcde );
	cursor: pointer;
	/* Blend from the low-score to high-score color using the
	   --wgs-heat-intensity custom property set per-cell by results.js
	   (0 = no responses/lowest score, 1 = the survey's highest-scoring
	   slot). color-mix() has broad enough support for this plugin's
	   target environments; a solid-color fallback isn't provided since
	   the low/high vars alone (no mix) would still render a reasonable,
	   just less granular, result on older browsers. */
	background: color-mix( in srgb, var( --wgs-heat-low ) calc( ( 1 - var( --wgs-heat-intensity, 0 ) ) * 100% ), var( --wgs-heat-high ) );
}

.wgs-heatmap__cell--empty {
	background: transparent;
	border: none;
	cursor: default;
}

.wgs-heatmap__badge {
	position: absolute;
	bottom: 2px;
	right: 4px;
	font-size: 0.7em;
	opacity: 0.85;
}

.wgs-results__cell-popover {
	position: fixed;
	top: 50%;
	left: 50%;
	transform: translate( -50%, -50% );
	background: var( --wgs-bg, #fff );
	color: var( --wgs-text, #1e1e1e );
	border: 1px solid var( --wgs-border, #dcdcde );
	border-radius: 6px;
	padding: 1.2em 1.5em;
	box-shadow: 0 4px 20px rgba( 0, 0, 0, 0.2 );
	max-width: 320px;
	z-index: 1000;
}

.wgs-results__cell-popover-close {
	position: absolute;
	top: 0.4em;
	right: 0.6em;
	background: none;
	border: none;
	font-size: 1.2em;
	cursor: pointer;
}

.wgs-results__cell-popover-content h4 {
	margin-top: 0;
}

/* ------------------------------------------------------------------
   Comments.
   ------------------------------------------------------------------ */

.wgs-comments {
	margin-top: 2em;
}

.wgs-comments__list {
	list-style: none;
	margin: 0 0 1em;
	padding: 0;
}

.wgs-comments__item {
	border-bottom: 1px solid var( --wgs-border, #dcdcde );
	padding: 0.8em 0;
}

.wgs-comments__item--pending {
	background: var( --wgs-cell-potentially, #fff8e5 );
	padding: 0.8em 1em;
	border-radius: 3px;
	border-bottom: none;
}

.wgs-comments__item-meta {
	font-size: 0.85em;
	color: var( --wgs-muted, #666 );
	display: flex;
	align-items: center;
	gap: 0.6em;
	margin-bottom: 0.3em;
}

.wgs-comments__pending-badge {
	background: var( --wgs-cell-potentially, #d6a625 );
	color: var( --wgs-cell-potentially-text, #1e1e1e );
}

.wgs-comments__form textarea {
	width: 100%;
	box-sizing: border-box;
}

.wgs-comments__honeypot {
	/* Off-screen rather than display:none/hidden — see the header comment
	   in survey-comments.php for why. */
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.wgs-comments__form-actions {
	margin-top: 0.5em;
	display: flex;
	align-items: center;
	gap: 1em;
}

.wgs-comments__cannot-comment-notice {
	background: var( --wgs-cell-unselected, #f0f0f1 );
	padding: 0.6em 1em;
	border-radius: 3px;
	font-size: 0.9em;
	color: var( --wgs-muted, #666 );
}

.wgs-theme-toggle {
	background: var( --wgs-cell-unselected );
	color: var( --wgs-text );
	border: 1px solid var( --wgs-border );
	border-radius: 4px;
	padding: 0.3em 0.8em;
	font-size: 0.85em;
	cursor: pointer;
	margin-bottom: 0.8em;
}

.wgs-theme-toggle:hover {
	opacity: 0.85;
}

/* ------------------------------------------------------------------
   Mobile list-view fallback (Phase 11): below ~600px, grid.js's
   renderGrid() renders a stacked list of collapsible date/weekday
   sections (renderMobileList()) instead of the dense CSS-grid layout
   (renderDenseGrid()) — a wide grid genuinely doesn't fit a phone
   screen. Both layouts share the same cell class (.wgs-grid__cell) and
   the same click/drag/keyboard wiring from wireGridInteraction(), so
   only the container layout differs here, not cell appearance/behavior.
   ------------------------------------------------------------------ */

.wgs-grid--mobile-list {
	display: flex;
	flex-direction: column;
	gap: 0.5em;
}

.wgs-grid__mobile-section {
	border: 1px solid var( --wgs-border );
	border-radius: 4px;
	overflow: hidden;
}

.wgs-grid__mobile-section summary {
	background: var( --wgs-cell-unselected );
	padding: 0.6em 0.8em;
	font-weight: 600;
	cursor: pointer;
}

.wgs-grid__mobile-rows {
	padding: 0.4em;
}

.wgs-grid__mobile-row {
	display: flex;
	align-items: center;
	gap: 0.8em;
	padding: 0.3em 0.4em;
}

.wgs-grid__mobile-row-time {
	flex: 0 0 5em;
	font-size: 0.9em;
	color: var( --wgs-muted );
}

.wgs-grid__mobile-row .wgs-grid__cell {
	flex: 1;
	min-height: 2.6em; /* slightly larger tap target than the dense grid's cells */
}

/* The mobile row already has its own dedicated .wgs-grid__mobile-row-time
   label to the left of the cell (see renderMobileList()/makeMobileRow()
   in grid.js), so the cell's own .wgs-grid__cell-time text (Task 7,
   needed in the dense grid layout) would just duplicate it here. */
.wgs-grid__mobile-row .wgs-grid__cell-time {
	display: none;
}

/* Below ~600px, the dense grid (still used as a fallback if JS hasn't
   run yet, or for the read-only heatmap in results.js, which does NOT
   get a mobile list variant in this pass — see the note below) keeps
   its own tightened spacing rather than switching layouts, since the
   heatmap's per-cell popover interaction doesn't map cleanly onto a
   list view the way the selection grid's click-to-cycle does. */
@media ( max-width: 600px ) {
	.wgs-grid,
	.wgs-heatmap {
		grid-template-columns: minmax( 70px, auto ) repeat( var( --wgs-grid-cols, 2 ), minmax( 44px, 1fr ) );
	}

	.wgs-grid__header,
	.wgs-grid__cell,
	.wgs-heatmap__header,
	.wgs-heatmap__cell {
		/* Bugfix: same em-relative-to-ambient-theme-font issue as the base
		   header rules above — anchor to the plugin's own font-size
		   variable instead. */
		font-size: calc( var( --wgs-grid-font-size, 21px ) * 0.8 );
	}

	/* Task 25 (mobile audit) bugfix: the rule above only targets the bare
	   `.wgs-grid` selector (one class), which has LOWER specificity than
	   `.wgs-grid.wgs-grid--calendar`'s own desktop grid-template-columns
	   rule (two classes, earlier in this file) — so it never actually
	   took effect for Task 21's calendar view; its day columns stayed at
	   the full 60px desktop floor even on a narrow phone (32px header +
	   7 × 60px days + 7 × 4px gaps ≈ 480px minimum, wider than a
	   320-375px viewport), needing horizontal scroll for what's
	   otherwise a fixed, modest 7-column layout that should reasonably
	   fit on its own per the plan. Narrowed here at matching (two-class)
	   specificity so it actually overrides. Deliberately does NOT also
	   match `.wgs-grid--year-mini` elements — those carry a third class
	   and so stay governed by the higher-specificity, DIFFERENTLY-tuned
	   rule below instead (year-mini needs the opposite adjustment; see
	   its comment). */
	.wgs-grid.wgs-grid--calendar {
		grid-template-columns: minmax( 22px, auto ) repeat( var( --wgs-grid-cols, 7 ), minmax( 36px, 1fr ) );
	}

	/* Task 25 (mobile audit) bugfix: at this same breakpoint, the year
	   view's 12 mini-months drop from 3-per-row to 1-per-row (see
	   .wgs-year-view__grid's own media query above) — each mini-month
	   now gets the FULL mobile width instead of a third of the desktop
	   width, so the extra-small 0.55x font-size/padding
	   `.wgs-grid--year-mini` uses to stay legible squeezed 3-across on
	   desktop is no longer appropriate; if anything, more room per month
	   calls for LARGER cells here, not smaller. Left un-overridden, that
	   0.55x would inherit down to every `.wgs-grid__cell` in a mini-month
	   and get multiplied by this very media query's own 0.8x cell
	   font-size rule above, compounding to a near-unreadable ~0.44x
	   combined scale — exactly backwards. This resets the multiplier
	   back to 1 (full size) at this breakpoint instead — same
	   specificity (three classes) as the desktop rule above, later in
	   source order, so it fully supersedes it (not compounds with it)
	   for elements matching both; combined with the 0.8x cell-level rule
	   above, mini-month cells land at the same ~0.8x every other view
	   gets at this breakpoint, not a further-shrunk fraction of it. The
	   grid-template-columns floor is widened too — not strictly required
	   for WIDTH (the day columns already use fluid `1fr` tracks that
	   stretch to fill however much room this container has regardless of
	   the floor), but as a genuine minimum touch-target size guarantee. */
	.wgs-grid.wgs-grid--calendar.wgs-grid--year-mini {
		grid-template-columns: minmax( 24px, auto ) repeat( var( --wgs-grid-cols, 7 ), minmax( 32px, 1fr ) );
		--wgs-grid-font-size: var( --wgs-grid-font-size, 21px );
		--wgs-grid-cell-padding: var( --wgs-grid-cell-padding, 15px );
	}
}
