/*
 * The catalogue.
 *
 * DENSE AND EXACT, NOT AIRY. Airy minimalism reads as unfinished; what reads as
 * expensive is precision — everything aligned to something, numbers that line
 * up down a column, hairlines rather than shadows, and one accent used once per
 * card instead of on every element.
 *
 * NO WEBFONT, EVER. Fetching one sends every visitor's address to a CDN, which
 * is why 0.21.0 took Google Fonts out. It also breaks the rupee: U+20B9 is
 * absent from the Latin subsets, so a price set in a webfont falls back
 * mid-number and looks broken. The system stack renders it correctly.
 *
 * WE ARE A RECTANGLE IN SOMEBODY ELSE'S THEME, so the family is inherited and
 * everything else — size, weight, tracking, rhythm, alignment — is ours. Sizes
 * are in em against the theme's own base, so this sits correctly in a theme
 * that runs 15px and one that runs 18px.
 *
 * ONE DESIGN IN TWO DENSITIES. .kv-cat--cards and .kv-cat--rows read exactly
 * the same markup; only the arrangement changes. Two sets of HTML would be two
 * places to fix a wording change, and they would drift.
 */

.kv-cat {
	--kv-ink: #14181d;
	--kv-sub: #6b7280;
	--kv-line: #e5e7eb;
	--kv-bg: transparent;
	--kv-card: #fff;
	--kv-accent: var(--kavita-accent, #2563eb);
	--kv-gap: 14px;
	color: var(--kv-ink);
	margin: 0 0 2em;
}

/*
 * NO prefers-color-scheme HERE, AND THAT IS THE FIX.
 *
 * This block used to repaint every card dark whenever the VISITOR'S OPERATING
 * SYSTEM was in dark mode -- which has nothing to do with the site the cards
 * are sitting in. A light theme viewed on a phone set to dark drew black cards
 * on a white page, and the owner's only clue was that it looked broken.
 *
 * The site is the authority, and the plugin already asks: Settings, Business,
 * "Booking form background". Left on Kavita's own light panel, the cards stay
 * light whatever the OS thinks. Switched to "Match my site", they paint no
 * background at all and inherit the theme's own colours, which is how a dark
 * theme gets dark cards -- because the theme is dark, not because the laptop is.
 */
.kv-cat--site {
	--kv-ink: inherit;
	--kv-sub: inherit;
	--kv-card: transparent;
	/* Drawn from the text colour, so the hairlines land correctly on a ground
	   this stylesheet cannot see. */
	--kv-line: color-mix(in srgb, currentColor 20%, transparent);
}
/* Muted text has to stay muted without a colour of its own to be muted with. */
.kv-cat--site .kv-about,
.kv-cat--site .kv-meta,
.kv-cat--site .kv-next-k,
.kv-cat--site .kv-cat-head span,
.kv-cat--site .kv-next--none { opacity: .72; }

/* ---------------- Category heading ---------------- */

.kv-cat-head {
	display: flex;
	align-items: baseline;
	gap: 10px;
	margin: 1.6em 0 0.7em;
	padding-bottom: 0.5em;
	border-bottom: 1px solid var(--kv-line);
}
.kv-cat-head:first-child { margin-top: 0; }
.kv-cat-head h2 {
	margin: 0;
	font-size: 1.05em;
	font-weight: 650;
	letter-spacing: -0.01em;
}
/* The count is a figure, so it is set like one. */
.kv-cat-head span {
	font: 500 0.78em/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	color: var(--kv-sub);
	padding: 3px 7px;
	border: 1px solid var(--kv-line);
	border-radius: 99px;
}

/* ---------------- Cards ---------------- */

.kv-cat-grid { display: grid; gap: var(--kv-gap); }

.kv-cat--cards .kv-cat-grid {
	grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
}

.kv-card {
	background: var(--kv-card);
	border: 1px solid var(--kv-line);
	border-radius: 12px;
	padding: 15px 16px 13px;
	display: flex;
	flex-direction: column;
	gap: 8px;
	/* A border that darkens, not a shadow that lifts. Shadows are what make a
	   plugin look like a plugin. */
	transition: border-color .18s ease-out, transform .18s ease-out;
}
.kv-card:hover { border-color: color-mix(in srgb, var(--kv-accent) 45%, var(--kv-line)); }

.kv-card-top {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
}
.kv-card-top h3 {
	margin: 0;
	font-size: 1em;
	font-weight: 620;
	letter-spacing: -0.011em;
	line-height: 1.3;
}

/* TABULAR FIGURES so every price in the column aligns to the digit. This is
   most of the difference between "designed" and "typed". */
.kv-price {
	font: 560 0.95em/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.kv-about {
	margin: 0;
	font-size: 0.88em;
	line-height: 1.5;
	color: var(--kv-sub);
}
.kv-more { font-size: 0.88em; line-height: 1.5; color: var(--kv-sub); }
.kv-more summary { cursor: pointer; }
.kv-more p { margin: 6px 0 0; }

.kv-meta {
	font-size: 0.8em;
	color: var(--kv-sub);
	letter-spacing: 0.005em;
}

/* ---------------- Faces ---------------- */

.kv-faces { display: flex; align-items: center; }
.kv-face {
	width: 26px;
	height: 26px;
	border-radius: 50%;
	object-fit: cover;
	border: 2px solid var(--kv-card);
	margin-left: -7px;
	background: var(--kv-line);
}
.kv-faces .kv-face:first-child { margin-left: 0; }
.kv-face--letter {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 0.72em;
	font-weight: 600;
	color: var(--kv-sub);
}

/* ---------------- Foot ---------------- */

.kv-card-foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	margin-top: auto;
	padding-top: 11px;
	border-top: 1px solid var(--kv-line);
}

.kv-next { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
/* The label is a micro-label; the value is the thing worth reading. */
.kv-next-k {
	font: 500 0.66em/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	text-transform: uppercase;
	letter-spacing: 0.07em;
	color: var(--kv-sub);
}
.kv-next-v {
	font-size: 0.86em;
	font-weight: 560;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.kv-next--none { font-size: 0.82em; color: var(--kv-sub); }
.kv-soon { display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 99px; font-size: 0.74em; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: #8a6d0a; background: rgba(201,162,39,.16); border: 1px solid rgba(201,162,39,.4); }
.kv-book--ghost { background: transparent; color: var(--kv-accent); }
.kv-book--ghost:hover, .kv-book--ghost:focus { color: var(--kv-accent); }

/* THE ONLY ACCENT ON THE CARD. Colour every element and none of them mean
   anything. Minimum 40px tall, because a thumb is not a mouse pointer. */
.kv-book {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 40px;
	padding: 0 17px;
	border: 1px solid var(--kv-accent);
	border-radius: 9px;
	background: var(--kv-accent);
	color: #fff;
	font-size: 0.87em;
	font-weight: 570;
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
	white-space: nowrap;
	transition: filter .16s ease-out;
}
.kv-book:hover,
.kv-book:focus { color: #fff; filter: brightness(1.08); }
.kv-book:focus-visible { outline: 2px solid var(--kv-accent); outline-offset: 2px; }

/* ---------------- Rows ---------------- */
/*
 * The dense reading of the same card: no boxes, hairlines only, everything on
 * one line where there is room. For a business with thirty services, boxes are
 * thirty rectangles to scan past.
 */

.kv-cat--rows .kv-cat-grid { gap: 0; }

.kv-cat--rows .kv-card {
	border: 0;
	border-bottom: 1px solid var(--kv-line);
	border-radius: 0;
	background: none;
	padding: 13px 2px;
	display: grid;
	grid-template-columns: 1fr auto auto;
	grid-template-areas:
		"name  price price"
		"about about about"
		"meta  next  book";
	align-items: center;
	gap: 4px 14px;
}
.kv-cat--rows .kv-card:hover { border-color: var(--kv-line); background: color-mix(in srgb, var(--kv-accent) 4%, transparent); }
.kv-cat--rows .kv-card-top { display: contents; }
.kv-cat--rows .kv-card-top h3 { grid-area: name; }
.kv-cat--rows .kv-price { grid-area: price; text-align: right; }
.kv-cat--rows .kv-about { grid-area: about; }
.kv-cat--rows .kv-meta { grid-area: meta; }
.kv-cat--rows .kv-faces { display: none; }
.kv-cat--rows .kv-card-foot {
	display: contents;
	border: 0;
	padding: 0;
	margin: 0;
}
.kv-cat--rows .kv-next { grid-area: next; justify-self: end; }
.kv-cat--rows .kv-book { grid-area: book; justify-self: end; }

/* ---------------- Small screens ---------------- */

@media (max-width: 560px) {
	.kv-cat--cards .kv-cat-grid { grid-template-columns: 1fr; }
	.kv-cat--rows .kv-card {
		grid-template-columns: 1fr auto;
		grid-template-areas:
			"name  price"
			"about about"
			"meta  meta"
			"next  book";
		gap: 5px 12px;
		padding: 15px 2px;
	}
	.kv-cat--rows .kv-next { justify-self: start; }
}

/* Somebody who has asked for less motion gets none of it. */
@media (prefers-reduced-motion: reduce) {
	.kv-card, .kv-book { transition: none; }
}

/* ---------------- The deposit ---------------- */
/*
 * Under the price, not beside it: the total is the fact and this is the
 * qualifier, so it reads second whatever the column width. Muted and smaller,
 * because a card that shouts two numbers has told you neither.
 */
.kv-dep {
	display: block;
	margin-top: 2px;
	font-size: 0.74em;
	font-weight: 500;
	color: var(--kv-sub);
	letter-spacing: 0.005em;
	white-space: nowrap;
}
.kv-cat--rows .kv-dep { display: inline; margin-left: 6px; }

/* ---------------- Packages ---------------- */
/*
 * The same card, marked once. A left edge in the accent is the whole
 * distinction — enough to say "this is a different kind of thing", not enough
 * to become a second design. Colouring the whole card would make the services
 * look like the afterthought.
 */
.kv-card--pkg { border-left: 3px solid var(--kv-accent); }
.kv-cat--rows .kv-card--pkg {
	border-left: 0;
	box-shadow: inset 3px 0 0 var(--kv-accent);
	padding-left: 12px;
}
/* A saving is a figure and is set like one. */
.kv-save .kv-next-v { font-variant-numeric: tabular-nums; }

/* ---------------- Events ---------------- */
/*
 * BROUGHT INTO THIS PAGE'S LANGUAGE, NOT REBUILT IN IT. The events app owns
 * tickets, early-bird pricing, waitlists, sold-out states and an attendee
 * register; re-drawing all of that here to gain matching corners would risk a
 * working booking flow for a cosmetic win. So the markup stays theirs and the
 * surface becomes ours: same border, same radius, same rhythm, same button.
 */
.kv-cat-events { margin: 0; }
.kv-cat-events .zy-events {
	display: grid;
	gap: var(--kv-gap);
	grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
}
.kv-cat-events .zy-event {
	background: var(--kv-card);
	border: 1px solid var(--kv-line);
	border-radius: 12px;
	padding: 15px 16px 13px;
	box-shadow: none;
	transition: border-color .18s ease-out;
}
.kv-cat-events .zy-event:hover { border-color: color-mix(in srgb, var(--kv-accent) 45%, var(--kv-line)); }
.kv-cat-events .zy-event.is-out { opacity: .6; }
.kv-cat-events .zy-event-title {
	margin: 0 0 2px;
	font-size: 1em;
	font-weight: 620;
	letter-spacing: -0.011em;
}
.kv-cat-events .zy-event-when { margin: 0 0 6px; font-size: 0.86em; font-weight: 540; font-variant-numeric: tabular-nums; }
.kv-cat-events .zy-event-desc,
.kv-cat-events .zy-muted { font-size: 0.86em; color: var(--kv-sub); }
.kv-cat-events .zy-event-meta { margin: 10px 0 0; padding-top: 11px; border-top: 1px solid var(--kv-line); }
.kv-cat-events .zy-price {
	font: 560 0.95em/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-variant-numeric: tabular-nums;
}
.kv-cat-events .zy-event-img { border-radius: 9px; margin-bottom: 10px; }
/* An event's button is the same affordance as a service's, so it looks it. */
.kv-cat-events .zy-btn {
	min-height: 40px;
	border-radius: 9px;
	font-size: 0.87em;
	font-weight: 570;
}

/* A section heading over a rendered app needs the same air as one over a grid. */
.kv-cat-events + .kv-cat-head,
.kv-cat-grid + .kv-cat-head { margin-top: 1.9em; }

/* ---------------- The gift card ---------------- */
/*
 * The one card that asks a question. The chips ARE the answer most of the time,
 * so they are the prominent control and the free field sits among them as one
 * more option rather than as a separate form below.
 */
.kv-card--gift { border-left: 3px solid var(--kv-accent); }
.kv-cat--rows .kv-card--gift {
	border-left: 0;
	box-shadow: inset 3px 0 0 var(--kv-accent);
	padding-left: 12px;
}
.kv-cat--rows .kv-card--gift { grid-template-areas: "name price" "about about" "amounts amounts" "err err" "meta book"; }
.kv-cat--rows .kv-amounts { grid-area: amounts; }
.kv-cat--rows .kv-gift-err { grid-area: err; }

.kv-amounts { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

/* A chip is a price, so it is set like one, and the chosen one is the only
   filled thing on the card besides the action. */
.kv-chip {
	min-height: 36px;
	padding: 0 12px;
	border: 1px solid var(--kv-line);
	border-radius: 99px;
	background: var(--kv-card);
	color: var(--kv-ink);
	font: 540 0.84em/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-variant-numeric: tabular-nums;
	cursor: pointer;
	transition: border-color .16s ease-out, background .16s ease-out;
}
.kv-chip:hover { border-color: color-mix(in srgb, var(--kv-accent) 50%, var(--kv-line)); }
.kv-chip.on {
	background: color-mix(in srgb, var(--kv-accent) 12%, transparent);
	border-color: var(--kv-accent);
	color: var(--kv-ink);
}
.kv-chip:focus-visible { outline: 2px solid var(--kv-accent); outline-offset: 2px; }

.kv-other { display: inline-flex; }
.kv-other input {
	width: 96px;
	min-height: 36px;
	padding: 0 12px;
	border: 1px dashed var(--kv-line);
	border-radius: 99px;
	background: transparent;
	color: var(--kv-ink);
	font: 540 0.84em/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-variant-numeric: tabular-nums;
}
.kv-other input:focus { border-style: solid; border-color: var(--kv-accent); outline: none; }

.kv-gift-err {
	margin: 0;
	font-size: 0.84em;
	color: #b32d2e;
}

/* Visible to a screen reader, not to an eye. */
.kv-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

@media (prefers-reduced-motion: reduce) {
	.kv-chip, .kv-other input { transition: none; }
}

/* ---------------- Tiles ---------------- */
/*
 * The third density, and the only one that drops information rather than
 * rearranging it. Cards explain, rows list, tiles recognise: many to a row,
 * the name and the price and nothing else, sized so a thumb hits one and not
 * its neighbour.
 *
 * WHAT IT HIDES IS THE POINT, so it is only the right choice when the names
 * alone tell somebody what the thing is -- "Dry Needling" does, "Package B"
 * does not. The description, the faces and the provider count are all still in
 * the markup, because a fourth arrangement of the same card must not become a
 * second set of HTML that drifts from the first.
 *
 * THE WHOLE TILE IS THE TARGET. At this size a button inside the tile would be
 * most of the tile anyway, so the button stretches to fill it and the tile is
 * the hit area -- which is also what makes it read as a phone home screen
 * rather than a shrunken card.
 */

.kv-cat--grid .kv-cat-grid {
	grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
	gap: 10px;
}

.kv-cat--grid .kv-card {
	padding: 13px 13px 11px;
	border-radius: 14px;
	gap: 5px;
	min-height: 128px;
}

/* Name over price, not beside it: at this width a baseline row would leave the
   name two words wide and the price hanging off the end. */
.kv-cat--grid .kv-card-top {
	display: block;
}
.kv-cat--grid .kv-card-top h3 {
	font-size: 0.94em;
	line-height: 1.28;
	/* Two lines, then an ellipsis -- a tile that grows to fit one long name
	   drags every tile in its row taller with it. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.kv-cat--grid .kv-price {
	display: block;
	margin-top: 4px;
	font-size: 1.02em;
	font-weight: 600;
}
.kv-cat--grid .kv-dep { display: none; }

.kv-cat--grid .kv-about,
.kv-cat--grid .kv-faces { display: none; }

/* Duration survives; "In person / Online / Group / N providers" does not. It is
   the one fact that changes what somebody is choosing between. */
.kv-cat--grid .kv-meta {
	font-size: 0.74em;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.kv-cat--grid .kv-card-foot {
	display: block;
	margin-top: auto;
	padding-top: 9px;
	border-top: 0;
}
.kv-cat--grid .kv-next { display: none; }
.kv-cat--grid .kv-next--none { display: none; }

.kv-cat--grid .kv-book {
	display: flex;
	width: 100%;
	min-height: 36px;
	padding: 0 10px;
	border-radius: 9px;
	font-size: 0.82em;
}

/* Two to a row on a small phone, never one: a single column of tiles is just
   cards with the words taken out. */
@media (max-width: 400px) {
	.kv-cat--grid .kv-cat-grid {
		grid-template-columns: repeat(2, 1fr);
		gap: 8px;
	}
	.kv-cat--grid .kv-card { min-height: 116px; }
}
