/**
 * The lesson hub, embedded in a lesson page.
 *
 * Loads after patron-portal.css, whose --kna-* custom properties are declared
 * on .kna-portal - the hub carries that class for exactly that reason. Every
 * selector is scoped under .kna-hub for the same reason the portal scopes under
 * .kna-portal: the theme's stylesheet is enqueued after this one and carries
 * rules like `button:not(.button-void)` at specificity 0,1,1, which would
 * otherwise win over a bare single class.
 *
 * THE PALETTE IS OVERRIDDEN, NOT INHERITED
 * .kna-portal's tokens are the blue/red set the dashboard is built on. This zone
 * is redesigned to the site's own language - yellow, cream, black - so it
 * redeclares every token it uses on .kna-hub. The dashboard keeps its own values
 * because nothing here is scoped loosely enough to reach it.
 *
 * The block below is shared with .kna-account: the dashboard was restyled to the
 * same system, and adding it to this selector list was part of that migration.
 *
 * SHARING TOKENS IS NOT SHARING RULES. The token block only decides what
 * `var(--kna-accent)` resolves to; it does nothing about which selectors match.
 * The trainer component - everything under `.kna-srs` - is therefore scoped to
 * `.kna-portal`, the class BOTH sections carry, so the flashcard, the grades,
 * the swap pill and the done screen are written once and appear on both pages.
 * Scoping them to `.kna-hub` left /konto's grade buttons falling through to
 * `.kna-portal .kna-button`, which paints them solid yellow.
 *
 * Page-specific rules stay under `.kna-hub` / `.kna-account` and come later in
 * the file, so they win on order at equal specificity.
 */

/* ------------------------------------------------------------- tokens -- */

.kna-hub,
.kna-account,
.kna-complete {

	/*
	 * Ink and body copy. Warm near-black rather than the dashboard's navy: this
	 * sits under a page whose text is black, and navy on cream reads as a
	 * different site.
	 */
	--kna-ink: #1b1b1b;
	--kna-ink-soft: #5c5c5c;

	/*
	 * DARKER THAN THE PROTOTYPE, DELIBERATELY.
	 *
	 * The handoff draws these as #8a8a8a and #9a9a9a, which measure 3.45:1 and
	 * 2.81:1 on white - and its own notes require 4.5:1. The design contradicts
	 * itself here and the stated rule wins, because what wears these is not
	 * decoration: the deck subtitle, the "Jak Ci poszło?" caption and the
	 * interval under every grade button ("1 min", "4 dni") are all information a
	 * learner is expected to read.
	 *
	 * The two-step hierarchy the prototype intended is kept - muted still reads
	 * ahead of faint - just moved into the range where both are legible.
	 * 5.74:1 and 4.88:1.
	 */
	--kna-ink-muted: #666666;
	--kna-ink-faint: #717171;

	--kna-ink-answer: #3b3b3b;

	/*
	 * Yellow is the one filled colour in the zone, and --kna-accent-ink is ink
	 * ON PURPOSE. patron-portal.css paints every primary button
	 * `background: var(--kna-accent); color: var(--kna-accent-ink)`, so leaving
	 * that token white would put white on #f5c518 - about 1.8:1 - everywhere at
	 * once. Never restore it to #fff for this section.
	 */
	--kna-accent: #f5c518;
	--kna-accent-hover: #e8b910;
	--kna-accent-ink: #1b1b1b;

	/* Cream: the flashcard, the player panel, every "this is patron stuff" fill. */
	--kna-cream: #fdf8e7;
	--kna-cream-line: #e0d6ae;
	--kna-cream-track: #eee2b8;

	/*
	 * Gold text, for uppercase labels on cream. Never for body copy.
	 *
	 * Darkened for the same reason as the greys above. The prototype's #a3925a
	 * on #fdf8e7 is 2.90:1 - the worst pair in the zone - and it carries the
	 * POLSKI / ANGIELSKI labels, which are the only thing telling a learner
	 * which way round the card is being asked. #8a7a3d was 4.01:1 on that same
	 * cream, so the badge failed too.
	 *
	 * Now 4.60:1 and 5.72:1. They read as a deeper bronze than the mock; that is
	 * the cost of the rule, and the rule is the handoff's own.
	 *
	 * --kna-gold-caret is exempt: it is the disclosure triangle, which sits
	 * beside its own text label and carries no information alone.
	 */
	--kna-gold: #7e7045;
	--kna-gold-strong: #6e6231;
	--kna-gold-caret: #c9a227;

	--kna-surface: #fff;
	--kna-surface-alt: #fdfcf8;
	--kna-panel: #faf8f3;

	/* Quiet control text: the swap pill and the Quizlet link. 8.86:1 on white. */
	--kna-ink-control: #4a4a4a;

	/* The transport circles' edge, on cream. Decorative - see the note there. */
	--kna-cream-edge: #e6d9a8;

	--kna-border: #e8e5dc;
	--kna-line-inner: #f0ede5;

	/* The dashboard's list rows, and the arrow that ends each of them. */
	--kna-line-row: #f5f2ea;
	--kna-arrow: #c9c4b4;

	/* Link hover, shared with the theme's own. */
	--kna-link-hover: #7a6206;
	--kna-line-control: #e2ded2;
	--kna-track: #eeebe2;
	--kna-dot-idle: #d6d1c4;

	/*
	 * Grading. Used as a 3px bottom border and a hover wash - never as the
	 * button's text colour, because at these tints none of the four would pass
	 * 4.5:1 against white. Position and label carry the meaning; colour only
	 * confirms it.
	 */
	--kna-grade-again: #c98b7a;
	--kna-grade-hard: #e0a83c;
	--kna-grade-good: #7a9a5b;
	--kna-grade-easy: #6b86a8;
	/*
	 * The "ukończona" tick on the dashboard's lesson list. A separate token from
	 * --kna-grade-good even though both are "the green one": that value is only
	 * ever a 3px border and a hover wash, where contrast rules do not bite, while
	 * this is 14.5px text carrying a fact. #7a9a5b would be 3.18:1 here.
	 */
	--kna-tick: #637d4a;

	--kna-grade-again-wash: #fbf4f2;
	--kna-grade-hard-wash: #fdf8ee;
	--kna-grade-good-wash: #f5f8f1;
	--kna-grade-easy-wash: #f3f6fa;

	/*
	 * Destructive actions and error states, kept off the accent. The dashboard
	 * could use --kna-accent for "Tak, wyczyść" because its accent was red; ours
	 * is the colour of the friendly primary button, which is the last thing a
	 * confirm-delete should look like.
	 */
	--kna-danger: #b3261e;

	/*
	 * Type. The design prototype used Figtree as a stand-in for the site's own
	 * display sans, which would ordinarily mean Lato - the theme's heading face.
	 *
	 * IT IS ROBOTO INSTEAD, AND THAT IS NOT AN OVERSIGHT.
	 *
	 * The theme loads Lato at 100/300/400 only; there is no real 700 or 900
	 * normal face in the @font-face block. Everything the design asks for here is
	 * 600-800, so under Lato every heading, every button label and the 40px
	 * flashcard term would be SYNTHETICALLY emboldened by the browser - smeared
	 * and unevenly weighted, worst at display sizes and worst again on Windows.
	 * Roboto is already the theme's body face, is loaded on every page anyway,
	 * and ships real 700 and 900.
	 *
	 * So the section is one family throughout, which is also what the prototype
	 * does. If Lato ever gains real bold faces, this is the line to revisit.
	 */
	--kna-font-display: "Roboto", "Lato", system-ui, sans-serif;
	--kna-font-body: "Roboto", system-ui, sans-serif;

	/*
	 * Weights, mapped rather than copied. The design asks for 800/700/600/500;
	 * Roboto loads 300/400/700/900, so the scale is named by role and resolved
	 * to a real face here once - 800 becomes 900, 600 becomes 700. Nothing in
	 * this file asks for a weight the browser has to invent.
	 */
	--kna-weight-display: 900;
	--kna-weight-bold: 700;
	--kna-weight-medium: 700;

	--kna-radius: 18px;
	--kna-radius-card-sm: 16px;
	--kna-radius-panel: 14px;
	--kna-radius-control: 12px;
	--kna-radius-tile: 9px;
	--kna-gap: 1rem;

	/* The only shadow in the zone, and only under filled yellow. No blurs. */
	--kna-shadow-key: 0 2px 0 rgba(0, 0, 0, 0.12);
	--kna-ease: 120ms ease;
}

/* ------------------------------------------------------------- section -- */

/*
 * The zone is a full band of the lesson page, not a box floated in it: white
 * ground, its own vertical rhythm, and a hairline rule that separates it from
 * the materials block above. Mobile-first, so these are the phone's numbers.
 */
.kna-hub {
	margin: 0;
	padding: 34px 0 40px;
	background: var(--kna-surface);
	color: var(--kna-ink);
	font-family: var(--kna-font-body);
	scroll-margin-top: 5rem;
}

/*
 * Focus lands here after a #resources deep link, so it must not look broken.
 *
 * /konto no longer sends anyone here - its resume card links to the lesson
 * itself, because it is shown to learners who cannot open this block. The
 * remaining deep links are the trainer's back-links (KNA_Patron_SRS_REST) and
 * the retired-dashboard redirect (KNA_Patron_Routing), so this still fires.
 */
.kna-hub:focus {
	outline: none;
}

.kna-hub:focus-visible {
	outline: 3px solid var(--kna-ink);
	outline-offset: 6px;
}

/*
 * Width is taken from the THEME's container rather than the prototype's literal
 * 1120px. The theme caps content at 1000px up to 1367px and 1230px above it, so
 * a hardcoded 1120 would overhang the lesson body at one breakpoint and fall
 * short at the other. The design's intent is "as wide as the page"; this is what
 * that means on this site.
 */
.kna-hub .kna-hub__inner {
	max-width: 1230px;
	margin: 0 auto;
	padding: 26px 16px 0;

	/*
	 * ONE GRID, THREE AREAS. The completion toggle is printed once, between the
	 * heading and the cards in source order, and placed by name: at the foot on
	 * a phone, beside the heading on a desktop. See the note in the template.
	 */
	display: flex;
	flex-direction: column;
	gap: 22px;
}

.kna-hub .kna-hub__zone {
	display: flex;
	flex-direction: column;
	gap: 22px;
}

.kna-hub .kna-hub__body {
	display: grid;
	gap: 20px;
	align-items: start;
}

/* Eyebrow ---------------------------------------------------------------- */

/*
 * THE HEADING IS THE BADGE.
 *
 * The theme's .material-access-badge grown to heading size and wrapped around
 * the heading itself: hairline black frame, rounded corner, Patronite mark
 * inset on the left. It replaced an eyebrow that repeated the heading, and then
 * a small pill beside it that read as a label rather than as part of the title.
 *
 * `inline-flex` on the h2 is what keeps the frame tight to the words instead of
 * stretching across the container - a full-width border here would read as a
 * section divider, which is exactly what this zone is trying not to have.
 *
 * COLOUR IS STILL OPEN. Black is the badge as the theme draws it everywhere
 * else; adding `kna-hub__title--gold` in the template swaps it for the zone's
 * gold-on-cream, and nothing else changes.
 */
.kna-hub .kna-hub__heading-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
	margin-bottom: 12px;
}

/* Heading and lede ------------------------------------------------------- */

.kna-hub .kna-hub__title {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	margin: 0;
	padding: 8px 18px 8px 12px;
	border: 1px solid var(--kna-ink);
	border-radius: 12px;
	background: var(--kna-surface);
	font-family: var(--kna-font-display);
	font-size: 28px;
	line-height: 1.1;
	font-weight: var(--kna-weight-display);
	letter-spacing: -0.02em;
	color: var(--kna-ink);
}

/*
 * Sized off the heading rather than fixed, so the mark keeps its proportion to
 * the words at both type sizes without a second rule at the breakpoint.
 */
.kna-hub .kna-hub__title-icon {
	flex: none;
	width: auto;
	height: 1.05em;
}

.kna-hub .kna-hub__title-text {
	display: inline-block;
}

/* The alternative: the zone's gold on cream rather than the site's black. */
.kna-hub .kna-hub__title--gold {
	border-color: var(--kna-cream-line);
	background: var(--kna-cream);
	color: var(--kna-gold-strong);
}

/* Says what the zone is, once, so the modules below need not each explain. */
.kna-hub .kna-hub__lede {
	margin: 0;
	max-width: 620px;
	font-size: 14.5px;
	line-height: 1.5;
	color: var(--kna-ink-soft);
	text-wrap: pretty;
}

/* Completion toggle ------------------------------------------------------

   Lives in the theme's .lesson-info-actions row, between "Pobierz Odcinek" and
   "Następny odcinek", so the three read as one path: take the file, mark it
   done, move on. It is therefore OUTSIDE every other scope in this file, which
   is why .kna-complete carries the token block at the top.

   The margins match the theme's own `.lesson-info-actions .button` rather than
   inheriting them, because this is deliberately not a `.button` - that class
   would bring the theme's filled styling with it and fight everything below. */

.kna-hub .kna-hub__zone > :first-child {
	margin-top: 0;
}

/* Completion toggle ------------------------------------------------------

   Lives in the theme's .lesson-info-actions row, between "Pobierz Odcinek" and
   "Następny odcinek", so the three read as one path: take the file, mark it
   done, move on. It is therefore OUTSIDE every other scope in this file, which
   is why .kna-complete carries the token block at the top.

   SIZING COMES FROM THE THEME, NOT FROM HERE.
   The button wears `button button-low`, the same pair its neighbours wear, so
   height, line-height, type, tracking, corner and this row's margins are the
   theme's and stay in step with it. Everything below changes appearance only.

   EVERY SELECTOR HERE QUALIFIES THE ELEMENT, deliberately. The theme dresses
   bare buttons through `button:not(.button-void)` at 0,1,1; a lone `.kna-complete`
   is 0,1,0 and loses to it, which is how this button ended up 56px tall beside
   two 42px ones. `button.kna-complete` matches that 0,1,1 and wins on order,
   because this stylesheet is enqueued after the theme's.

   Note what is NOT overridden: `button:not(.button-void).button-low` sets the
   height at 0,2,1 and keeps it, which is exactly the point - the theme decides
   how tall its buttons are. */

/* Vanishes from the layout so the button is a flex child of the row, like its
   two neighbours. Empty for a logged-out reader, which then renders nothing. */
.kna-complete-slot {
	display: contents;
}

button.kna-complete {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;

	/* 14 + 20 + 8 = the 42px left inset the neighbours give their icons. */
	padding: 4px 30px 4px 14px;

	border: 2px solid var(--kna-accent);
	background: var(--kna-surface);
	color: var(--kna-ink);
	cursor: pointer;
	transition: background-color var(--kna-ease), border-color var(--kna-ease), color var(--kna-ease);
}

/*
 * TOUCH LATCHES :hover AFTER A TAP, and below 480px the theme repaints a hovered
 * button light yellow (0,2,1). Left alone that turned a tapped, unmarked button
 * yellow and hid its yellow circle inside the fill. So hover is first pinned to
 * whatever the resting state already is - the block after this one then puts the
 * real hover back for pointers that actually have one.
 */
button.kna-complete:hover {
	background: var(--kna-surface);
	border-color: var(--kna-accent);
	color: var(--kna-ink);
}

button.kna-complete.is-complete:hover {
	background: var(--kna-accent);
	border-color: var(--kna-accent);
	color: var(--kna-ink);
}

/*
 * HOVER IS FOR POINTERS THAT CAN HOVER.
 *
 * Filling yellow on hover is a fine desktop affordance and a bug on a phone:
 * :hover latches after a tap and stays until the reader touches something else,
 * so an unmarked button sat there filled yellow - looking marked - with its
 * yellow circle invisible against the new background.
 */
@media (hover: hover) {

	button.kna-complete:hover {
		background: var(--kna-accent);
		border-color: var(--kna-accent);
		color: var(--kna-ink);
	}

	/* The frame's colour would disappear into the fill, so the circle inks in. */
	button.kna-complete:hover .kna-complete__tick {
		border-color: var(--kna-ink);
	}
}

/*
 * FOCUS HAS TO BE STATED, NOT LEFT TO THE THEME.
 *
 * Below 480px the theme paints `button:not(.button-void):focus` a light yellow
 * - 0,2,1, which beats the 0,1,1 that sets our fill. A tapped button therefore
 * changed colour and swallowed its own circle. These rules match that 0,2,1 and
 * win on order; the marked pair goes to 0,3,1 so that filled yellow, which is
 * genuinely the state there, survives being focused.
 */
button.kna-complete:focus {
	background: var(--kna-surface);
	border-color: var(--kna-accent);
	color: var(--kna-ink);
}

button.kna-complete.is-complete:focus {
	background: var(--kna-accent);
	border-color: var(--kna-accent);
	color: var(--kna-ink);
}

button.kna-complete:focus-visible {
	outline: 2px solid var(--kna-ink);
	outline-offset: 2px;
}

/*
 * The empty circle, and the reason the button keeps one width in both states -
 * a mark appearing only on completion would shift the label sideways at the
 * exact moment the reader is looking at it. It takes the frame's colour, so the
 * unmarked button reads as one yellow-outlined object.
 */
.kna-complete .kna-complete__tick {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 20px;
	height: 20px;
	border: 2px solid var(--kna-accent);
	border-radius: 50%;
	background: transparent;
	color: transparent;
	font-size: 11px;
	line-height: 1;
	transition: background-color var(--kna-ease), border-color var(--kna-ease), color var(--kna-ease);
}

/* Marked: filled yellow, circle inked in, tick showing. */
button.kna-complete[aria-pressed="true"],
button.kna-complete.is-complete {
	background: var(--kna-accent);
	border-color: var(--kna-accent);
	color: var(--kna-ink);
}

.kna-complete.is-complete .kna-complete__tick {
	border-color: var(--kna-ink);
	background: var(--kna-ink);
	color: var(--kna-surface);
}

button.kna-complete.has-error {
	border-color: var(--kna-danger);
	color: var(--kna-danger);
}

button.kna-complete[disabled] {
	opacity: 0.6;
	cursor: progress;
}

.kna-complete.is-saving::after {
	content: "";
	width: 0.85em;
	height: 0.85em;
	margin-left: 0.5rem;
	border: 2px solid currentColor;
	border-right-color: transparent;
	border-radius: 50%;
	animation: kna-hub-spin 0.7s linear infinite;
}

@keyframes kna-hub-spin {

	to {
		transform: rotate(360deg);
	}
}

@media (prefers-reduced-motion: reduce) {

	button.kna-complete {
		transition: none;
	}

	/* Losing the spin would leave a lopsided static ring; close the gap instead. */
	.kna-complete.is-saving::after {
		animation: none;
		border-right-color: currentColor;
		opacity: 0.5;
	}
}

/* ---------------------------------------------------------------- vocab -- */

/*
 * The locked trainer's three-word taster. Not in the design - which only draws
 * the entitled state - so it is derived: it stands where the flashcard stands,
 * on the same cream, separated by the same dashed rule the revealed answer
 * uses. It should read as the trainer with the interaction removed, because
 * that is exactly what is being sold.
 */
.kna-hub .kna-hub__preview {
	padding: 26px 18px;
	background: var(--kna-cream);
	text-align: center;
}

.kna-hub .kna-hub__vocab {
	margin: 0;
}

.kna-hub .kna-hub__vocab-row {
	padding: 12px 0;
	border-bottom: 1px dashed var(--kna-cream-line);
}

.kna-hub .kna-hub__vocab-row:first-child {
	padding-top: 0;
}

.kna-hub .kna-hub__vocab-row:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

.kna-hub .kna-hub__vocab dt {
	margin: 0;
	font-family: var(--kna-font-display);
	font-size: 22px;
	line-height: 1.2;
	font-weight: var(--kna-weight-display);
	letter-spacing: -0.02em;
	color: var(--kna-ink);
}

.kna-hub .kna-hub__vocab dd {
	margin: 4px 0 0;
	font-size: 16px;
	font-weight: var(--kna-weight-medium);
	color: var(--kna-ink-answer);
}

.kna-hub .kna-hub__vocab-more {
	margin: 14px 0 0;
	font-size: 12.5px;
	color: var(--kna-gold);
}

/* -------------------------------------------------------------- modules -- */

/*
 * One card per Patron asset. Both cards share a frame; what differs is that the
 * trainer's contents are edge-to-edge BANDS (header rule, stats bar, cream
 * flashcard) while MINI is a padded card with an inset panel. So the card itself
 * carries no padding and every band brings its own - `overflow: hidden` is what
 * keeps the bands inside the 18px corner.
 */
.kna-hub .kna-hub__module {
	margin: 0;
	padding: 0;
	background: var(--kna-surface);
	border: 1px solid var(--kna-border);
	border-radius: var(--kna-radius-card-sm);
	overflow: hidden;
}

.kna-hub .kna-hub__module-header {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 12px;
	padding: 18px 18px 14px;
	border-bottom: 1px solid var(--kna-line-inner);
}

/* MINI leads with an icon beside its heading, so that row is horizontal. */
.kna-hub .kna-hub__module--mini .kna-hub__module-header {
	flex-direction: row;
	align-items: center;
	gap: 10px;
	padding: 22px 18px 0;
	border-bottom: 0;
}

.kna-hub .kna-hub__module-heading {
	min-width: 0;
}

/*
 * The authored icon, in the design's cream tile. Sized to the tile rather than
 * the image because what arrives is a hand-drawn line illustration whose aspect
 * ratio is the editor's business, not ours.
 */
.kna-hub .kna-hub__module-icon {
	box-sizing: content-box;
	width: 22px;
	height: 22px;
	flex: none;
	padding: 3px;
	background: var(--kna-cream);
	border-radius: var(--kna-radius-tile);
	object-fit: contain;
}

.kna-hub .kna-hub__module-title {
	margin: 0;
	font-family: var(--kna-font-display);
	font-size: 17px;
	line-height: 1.25;
	font-weight: var(--kna-weight-bold);
	letter-spacing: -0.01em;
	color: var(--kna-ink);
}

.kna-hub .kna-hub__module--mini .kna-hub__module-title {
	flex: 1 1 auto;
	font-size: 17px;
}

.kna-hub .kna-hub__module-sub {
	margin: 3px 0 0;
	font-size: 12.5px;
	line-height: 1.35;
	color: var(--kna-ink-muted);
}

/*
 * The slot the swap pill is reparented into. Empty until srs-view.js mounts, so
 * it must not reserve space of its own - :empty keeps the header from carrying
 * a 12px gap around nothing while JavaScript is still booting.
 */
.kna-hub .kna-hub__module-tools:empty {
	display: none;
}

/*
 * The tier badge, shown wherever the module is locked. Derived from the
 * section's own eyebrow rather than invented: same uppercase gold lettering, on
 * the cream that means "patron" everywhere else in the zone. The dark pill it
 * replaces read as a system label; this reads as a price tag, which is what it
 * is.
 */
.kna-hub .kna-hub__badge {
	align-self: flex-start;
	flex: none;
	padding: 5px 11px;
	background: var(--kna-cream);
	color: var(--kna-gold-strong);
	border-radius: 999px;
	font-size: 11px;
	font-weight: var(--kna-weight-bold);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	white-space: nowrap;
}

.kna-hub .kna-hub__module-body {
	margin: 0;
	padding: 8px 18px 0;
	font-size: 14px;
	line-height: 1.5;
	color: var(--kna-ink-soft);
	text-wrap: pretty;
}

/* Editor-authored markup arrives with its own margins. */
.kna-hub .kna-hub__module-body > :first-child {
	margin-top: 0;
}

.kna-hub .kna-hub__module-body > :last-child {
	margin-bottom: 0;
}

/*
 * No recording yet. The cream panel is the player's own, so the module keeps its
 * shape and the absence reads as "not yet" rather than as a failure to load.
 */
.kna-hub .kna-hub__pending {
	margin: 16px;
	padding: 22px 18px;
	background: var(--kna-cream);
	border-radius: var(--kna-radius-panel);
	font-size: 13.5px;
	line-height: 1.5;
	text-align: center;
	color: var(--kna-gold-strong);
}

.kna-hub .kna-hub__locked {
	margin: 0;
	padding: 0 16px 18px;
}

/* The trainer's paywall sits under a full-bleed preview, so it needs the gap. */
.kna-hub .kna-hub__module--cards .kna-hub__locked {
	padding-top: 18px;
}

@media (prefers-reduced-motion: reduce) {

	.kna-hub * {
		transition: none !important;
		animation: none !important;
	}

}

/* ------------------------------------------------------------ review ---- */

/*
 * The mount. It is no longer a padded grey box: the trainer's parts are now
 * full-bleed bands of the card - stats bar, cream flashcard, grading row - so
 * this element only stacks them and reserves height before JavaScript runs.
 */
.kna-portal .kna-srs {
	display: flex;
	flex-direction: column;
	padding: 0;
	background: transparent;
	border-radius: 0;
	text-align: left;

	/*
	 * Reserves the height of a mounted card BEFORE JavaScript runs. Sized for
	 * the tallest ordinary state - bar, flashcard and the grade grid wrapped to
	 * 2x2 - because the grid only collapses to one row at 35em.
	 */
	min-height: 25rem;
}

.kna-portal .kna-srs:focus {
	outline: none;
}

/* Stats bar --------------------------------------------------------------

   One band across the card: what the deck looks like on the left, where this
   round has got to on the right. */

.kna-portal .kna-srs__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 11px 18px;
	background: var(--kna-surface-alt);
	border-bottom: 1px solid var(--kna-line-inner);
}

.kna-portal .kna-srs__summary {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 4px 12px;
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 12px;
	font-weight: 400;
	color: var(--kna-ink-soft);
}

.kna-portal .kna-srs__count {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	white-space: nowrap;
}

/*
 * The dot repeats what the label already says, so it is decoration in the
 * strict sense. Hidden from assistive tech in the markup; here it is only ever
 * a colour.
 */
.kna-portal .kna-srs__count-dot {
	display: inline-block;
	flex: none;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: var(--kna-dot-idle);
}

.kna-portal .kna-srs__count--known .kna-srs__count-dot { background: var(--kna-grade-good); }
.kna-portal .kna-srs__count--learning .kna-srs__count-dot { background: var(--kna-accent); }
.kna-portal .kna-srs__count--fresh .kna-srs__count-dot { background: var(--kna-dot-idle); }
.kna-portal .kna-srs__count--suspended .kna-srs__count-dot { background: var(--kna-line-control); }

.kna-portal .kna-srs__count-n {
	font-weight: var(--kna-weight-bold);
	color: var(--kna-ink);
	font-variant-numeric: tabular-nums;
}

.kna-portal .kna-srs__bar-end {
	display: flex;
	align-items: center;
	gap: 10px;
	flex: none;
}

.kna-portal .kna-srs__status {
	margin: 0;
	font-size: 12px;
	color: var(--kna-ink-faint);
	font-variant-numeric: tabular-nums;
}

/*
 * The direction, kept for the live region and taken off the screen. See
 * paintStatus() in srs-view.js for why it cannot simply be dropped.
 */
.kna-portal .kna-srs__dir-note {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.kna-portal .kna-srs__track {
	flex: none;
	width: 48px;
	height: 5px;
	border-radius: 3px;
	background: var(--kna-track);
	overflow: hidden;
}

.kna-portal .kna-srs__track-fill {
	display: block;
	width: 0;
	height: 100%;
	background: var(--kna-accent);
	transition: width var(--kna-ease);
}

/* The flashcard ---------------------------------------------------------- */

.kna-portal .kna-srs__stage {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0;
	min-height: 0;
	padding: 32px 18px 26px;
	background: var(--kna-cream);
	text-align: center;
}

/*
 * "Polski" / "Angielski". Small, gold, and above the line they describe - they
 * exist because the card can be asked either way round, and a bare word does
 * not say whether you are being asked to recognise it or to produce it.
 */
.kna-portal .kna-srs__side-label {
	margin: 0 0 12px;
	font-size: 10.5px;
	font-weight: var(--kna-weight-bold);
	line-height: 1.2;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--kna-gold);
}

.kna-portal .kna-srs__term {
	margin: 0;
	font-family: var(--kna-font-display);
	font-size: 30px;
	line-height: 1.1;
	font-weight: var(--kna-weight-display);
	letter-spacing: -0.02em;
	color: var(--kna-ink);
	text-wrap: balance;
}

/*
 * The revealed side. The dashed rule is what separates it from the prompt, so
 * it belongs to this block rather than to the stage - when the answer is
 * hidden, the rule must go with it.
 */
.kna-portal .kna-srs__answer {
	display: inline-block;
	min-width: 200px;
	max-width: 100%;
	margin-top: 12px;
	padding-top: 12px;
	border-top: 1px dashed var(--kna-cream-line);
}

.kna-portal .kna-srs__answer .kna-srs__side-label {
	margin-bottom: 5px;
}

.kna-portal .kna-srs__back {
	margin: 0;
	font-size: 20px;
	line-height: 1.25;
	font-weight: var(--kna-weight-medium);
	color: var(--kna-ink-answer);
}

/*
 * The sample sentence. Not in the design, which draws a card that happens not
 * to have one - so it is derived: quieter than the answer it belongs to, on the
 * same cream, sharing the answer block's width.
 */
.kna-portal .kna-srs__example {
	margin: 8px 0 0;
	font-size: 13px;
	line-height: 1.45;
	font-style: italic;
	color: var(--kna-gold);
}

/*
 * Pokaż / Ukryj odpowiedź: the one filled control on the card, and the only
 * place a shadow appears in the whole zone.
 */
.kna-portal .kna-srs__reveal {
	width: 100%;
	min-height: 44px;
	margin-top: 22px;
	padding: 15px 20px;
	border: 0;
	border-radius: 999px;
	background: var(--kna-accent);
	color: var(--kna-ink);
	font-family: var(--kna-font-body);
	font-size: 15px;
	font-weight: var(--kna-weight-bold);
	line-height: 1;
	box-shadow: var(--kna-shadow-key);
	transition: background-color var(--kna-ease);
}

.kna-portal .kna-srs__reveal:hover,
.kna-portal .kna-srs__reveal:focus-visible {
	background: var(--kna-accent-hover);
	color: var(--kna-ink);
}

/* Grading ---------------------------------------------------------------- */

.kna-portal .kna-srs__grading {
	padding: 16px 18px 20px;
}

.kna-portal .kna-srs__grading-caption {
	margin: 0 0 10px;
	font-size: 12px;
	color: var(--kna-ink-muted);
}

.kna-portal .kna-srs__grades {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 9px;
	margin: 0;
}

.kna-portal .kna-srs__grade {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	min-height: 44px;
	padding: 13px 8px;
	background: var(--kna-surface);
	border: 1px solid var(--kna-line-control);
	border-bottom-width: 3px;
	border-radius: var(--kna-radius-control);
	transition: background-color var(--kna-ease), border-color var(--kna-ease);
}

.kna-portal .kna-srs__grade-label {
	font-family: var(--kna-font-body);
	font-size: 14px;
	font-weight: var(--kna-weight-bold);
	line-height: 1.2;
	color: var(--kna-ink);
}

.kna-portal .kna-srs__grade-when {
	font-size: 11px;
	font-weight: 400;
	line-height: 1.2;
	opacity: 1;
	color: var(--kna-ink-faint);
}

/*
 * Colour carries meaning here, so each grade also differs in position and
 * label - never colour alone. It is applied ONLY as the 3px bottom edge and a
 * hover wash: at these tints none of the four would pass 4.5:1 as text, which
 * is exactly why the label stays ink.
 */
.kna-portal .kna-srs__grade--again { border-bottom-color: var(--kna-grade-again); }
.kna-portal .kna-srs__grade--hard  { border-bottom-color: var(--kna-grade-hard); }
.kna-portal .kna-srs__grade--good  { border-bottom-color: var(--kna-grade-good); }
.kna-portal .kna-srs__grade--easy  { border-bottom-color: var(--kna-grade-easy); }

.kna-portal .kna-srs__grade--again:hover { background: var(--kna-grade-again-wash); }
.kna-portal .kna-srs__grade--hard:hover  { background: var(--kna-grade-hard-wash); }
.kna-portal .kna-srs__grade--good:hover  { background: var(--kna-grade-good-wash); }
.kna-portal .kna-srs__grade--easy:hover  { background: var(--kna-grade-easy-wash); }

.kna-portal .kna-srs__grade[disabled],
.kna-portal .kna-srs__swap[disabled],
.kna-portal .kna-srs__reveal[disabled] {
	opacity: 0.55;
	cursor: progress;
}

/* The direction pill ------------------------------------------------------

   Reparented into the card header by srs-view.js, so these rules describe it
   where it lands, not where it is built. Deliberately quieter than everything
   on the card: this changes how the deck asks its questions; it is not a way to
   answer one, and sizing it like a grade would invite it being pressed as if it
   were. */

.kna-portal .kna-srs__tools {
	display: flex;
	justify-content: flex-end;
	margin: 0;
}

.kna-portal .kna-srs__swap {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	width: 100%;
	min-height: 40px;
	padding: 10px 15px;
	background: var(--kna-surface);
	border: 1px solid var(--kna-line-control);
	border-radius: 999px;
	font-family: var(--kna-font-body);
	font-size: 12.5px;
	font-weight: 400;
	line-height: 1;
	color: var(--kna-ink-control);
	transition: border-color var(--kna-ease), color var(--kna-ease);
}

.kna-portal .kna-srs__swap:hover,
.kna-portal .kna-srs__swap:focus-visible {
	border-color: var(--kna-ink);
	color: var(--kna-ink);
	background: var(--kna-surface);
}

.kna-portal .kna-srs__swap-state {
	font-variant-numeric: tabular-nums;
	font-weight: var(--kna-weight-medium);
	opacity: 1;
	color: var(--kna-gold-strong);
	white-space: nowrap;
}

/* --------------------------------------------------- the [hidden] guard ---

   THIS RULE IS LOAD-BEARING. DO NOT REMOVE IT.

   `hidden` is a UA-level `display: none`, which means ANY author-level display
   rule beats it - and this component sets `display: grid` on the grade row,
   `display: flex` on the done panel and `display: inline-flex` on every button.
   Without this guard, every `node.hidden = true` in srs-view.js is silently a
   no-op, and the symptoms are not obviously CSS at all:

     - the four grade buttons sit on screen before the answer is revealed, and
       clicking one does nothing, because answerCard() correctly refuses to
       grade a card the learner has not looked at yet;
     - the done panel renders under the live card, so "Zakończ trening" is
       visible during a normal review and does nothing when pressed.

   Both were reported as "the buttons don't work". They were working; they were
   being asked to act on a state the learner was not actually in. */

.kna-portal [hidden] {
	display: none !important;
}

/* WHY THE HUB'S HALF IS SCOPED TO THE WHOLE SECTION, NOT TO .kna-srs

   It used to be `.kna-portal .kna-srs [hidden]`, which was enough while every
   control the component hides lived inside the mount. The swap pill does not
   any more: srs-view.js reparents it into the card header, which is PHP, and
   `tools.hidden = true` is still how the component keeps it off screen before
   mount and on the done screen. Outside the old selector that assignment went
   back to being a no-op - beaten by this file's own `.kna-srs__tools
   { display: flex }` - and the pill sat there offering to swap a card that was
   not on screen.

   Widening it is not a workaround. `hidden` means hidden; there is no element
   in this zone for which that should be negotiable. */
/* --------------------------------------------------- trainer chrome ---- */

/* Static PHP siblings of .kna-srs. Kept outside the element srs-view.js
   rebuilds so nothing here can be destroyed by a re-render - which is also why
   the Quizlet link survives on the done screen, where it is arguably most
   useful. */

.kna-portal .kna-srs__footer {
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin: 0 18px;
	padding: 14px 0 20px;
	border-top: 1px solid var(--kna-line-inner);
}

/* Quizlet ---------------------------------------------------------------- */

.kna-hub .kna-hub__quizlet {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	min-height: 40px;
	padding: 12px;
	background: var(--kna-surface);
	border: 1px solid var(--kna-line-control);
	border-radius: 999px;
	color: var(--kna-ink-control);
	font-family: var(--kna-font-body);
	font-size: 13px;
	font-weight: 400;
	line-height: 1;
	text-decoration: none;
	transition: border-color var(--kna-ease), color var(--kna-ease);
}

.kna-hub .kna-hub__quizlet:hover,
.kna-hub .kna-hub__quizlet:focus-visible {
	border-color: var(--kna-ink);
	color: var(--kna-ink);
	background: var(--kna-surface);
}

/*
 * The arrow is the external-link affordance, per the design. aria-hidden in the
 * markup: the link already opens in a new tab and says so to assistive tech
 * through rel/target conventions, and "north east arrow" read aloud is noise.
 */
.kna-hub .kna-hub__quizlet-glyph {
	font-size: 12px;
	line-height: 1;
}

.kna-portal .kna-srs__noscript {
	margin: 16px 18px 0;
	font-size: 13.5px;
	line-height: 1.5;
	color: var(--kna-ink-soft);
}

/* Skeleton ---------------------------------------------------------------

   This exists to hold the box's height, not to decorate it. The trainer is
   the first module in the zone and .kna-srs is empty until JavaScript fills
   it, so without something occupying the space the MINI card below jumps
   20-150ms into the page's life. srs-view.js removes this on mount.

   Shaped like the card it stands in for - a cream block with a bar where the
   term goes - so the swap is not itself a visible change.

   No animation: it is on screen for a fraction of a second, and a pulse that
   brief reads as a flicker rather than as progress. */

.kna-portal .kna-srs__skeleton {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 12px;
	padding: 46px 18px 26px;
	background: var(--kna-cream);
}

.kna-portal .kna-srs__skeleton-term,
.kna-portal .kna-srs__skeleton-line {
	display: block;
	height: 1.4rem;
	border-radius: 6px;
	background: var(--kna-cream-track);
}

.kna-portal .kna-srs__skeleton-term {
	width: 60%;
	height: 1.9rem;
}

.kna-portal .kna-srs__skeleton-line {
	width: 40%;
}

.kna-portal .kna-srs__skeleton-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 9px;
	width: 100%;
	margin-top: 18px;
}

.kna-portal .kna-srs__skeleton-grid span {
	display: block;
	min-height: 44px;
	border: 1px solid var(--kna-cream-line);
	border-radius: var(--kna-radius-control);
}

/* Legend -----------------------------------------------------------------

   A native disclosure. The default triangle is replaced by a gold caret that
   turns 90 degrees on open, because the UA marker cannot be coloured and sits
   at the wrong optical weight beside 13.5px text. */

.kna-portal .kna-srs__legend {
	margin: 0;
	font-size: 13.5px;
}

.kna-portal .kna-srs__legend summary {
	display: flex;
	align-items: center;
	gap: 7px;
	padding: 0;
	list-style: none;
	cursor: pointer;
	color: var(--kna-ink-soft);
	font-size: 13.5px;
	font-weight: 400;
	transition: color var(--kna-ease);
}

.kna-portal .kna-srs__legend summary::-webkit-details-marker {
	display: none;
}

.kna-portal .kna-srs__legend summary::before {
	content: "\25B8";
	flex: none;
	color: var(--kna-gold-caret);
	font-size: 12px;
	line-height: 1;
	transition: transform 150ms ease;
}

.kna-portal .kna-srs__legend[open] summary::before {
	transform: rotate(90deg);
}

.kna-portal .kna-srs__legend summary:hover,
.kna-portal .kna-srs__legend summary:focus-visible {
	color: var(--kna-ink);
}

.kna-portal .kna-srs__legend p {
	margin: 10px 0 0;
	font-size: 13px;
	line-height: 1.5;
	color: var(--kna-ink-soft);
}

.kna-portal .kna-srs__legend-list {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 6px 12px;
	margin: 12px 0 0;
	font-size: 13px;
	line-height: 1.5;
}

.kna-portal .kna-srs__legend-list dt {
	font-weight: var(--kna-weight-bold);
	color: var(--kna-ink);
}

.kna-portal .kna-srs__legend-list dd {
	margin: 0;
	color: var(--kna-ink-soft);
}

/* Nothing to press on a touch device, so the hint is only noise there. */
@media (hover: none) and (pointer: coarse) {

	.kna-portal .kna-srs__kbd-hint {
		display: none;
	}
}

/* ------------------------------------------------ summary and done ------ */

/*
 * NONE OF THIS IS IN THE DESIGN.
 *
 * The handoff draws one state: an entitled patron mid-review. The trainer also
 * has a done screen, a next-round screen, a daily-cap screen, an extra-practice
 * mode, a two-step reset and a leech offer. All of it is derived from the drawn
 * state rather than invented: the done panel stands where the flashcard stands
 * and takes its cream, the one onward action takes the flashcard's yellow pill,
 * and everything optional stays a quiet outline pill so it cannot compete.
 */

.kna-portal .kna-srs__done {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 14px;
	padding: 32px 18px 26px;
	background: var(--kna-cream);
	text-align: center;
}

.kna-portal .kna-srs__done-note {
	margin: 0;
	font-size: 14px;
	line-height: 1.5;
	color: var(--kna-ink-soft);
	text-wrap: pretty;
}

/* The headline on the done screen - "Gotowe na dziś!" and friends. */
.kna-portal .kna-srs__done > p:first-child {
	font-family: var(--kna-font-display);
	font-size: 20px;
	font-weight: var(--kna-weight-bold);
	letter-spacing: -0.01em;
	color: var(--kna-ink);
}

.kna-portal .kna-srs__practice,
.kna-portal .kna-srs__reset {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8px;
	width: 100%;
}

.kna-portal .kna-srs__practice-note,
.kna-portal .kna-srs__reset-warning,
.kna-portal .kna-srs__reset-message {
	margin: 0;
	font-size: 12.5px;
	line-height: 1.45;
	color: var(--kna-ink-soft);
}

/*
 * Next round: the primary action, and while cards are still waiting it is the
 * ONLY thing on the done screen. Same filled pill as "Pokaż odpowiedź", because
 * it occupies the same place and answers the same question - what now?
 */
.kna-portal .kna-srs__round-next {
	width: 100%;
	min-height: 48px;
	padding: 15px 20px;
	border: 0;
	border-radius: 999px;
	background: var(--kna-accent);
	color: var(--kna-ink);
	font-family: var(--kna-font-body);
	font-size: 15px;
	font-weight: var(--kna-weight-bold);
	line-height: 1;
	box-shadow: var(--kna-shadow-key);
	transition: background-color var(--kna-ease);
}

.kna-portal .kna-srs__round-next:hover,
.kna-portal .kna-srs__round-next:focus-visible {
	background: var(--kna-accent-hover);
	color: var(--kna-ink);
}

/*
 * Every optional onward action shares one quiet outline pill, so that none of
 * them reads as the thing to do next. On cream rather than white, so the border
 * needs the warmer line to sit right.
 */
.kna-portal .kna-srs__bonus,
.kna-portal .kna-srs__handoff,
.kna-portal .kna-srs__revive,
.kna-portal .kna-srs__leech-aside,
.kna-portal .kna-srs__practice-start,
.kna-portal .kna-srs__practice-end,
.kna-portal .kna-srs__next {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 44px;
	padding: 12px 18px;
	background: var(--kna-surface);
	border: 1px solid var(--kna-cream-line);
	border-radius: 999px;
	color: var(--kna-ink);
	font-family: var(--kna-font-body);
	font-size: 13.5px;
	font-weight: var(--kna-weight-medium);
	line-height: 1.2;
	text-align: center;
	text-decoration: none;
	transition: border-color var(--kna-ease), background-color var(--kna-ease);
}

.kna-portal .kna-srs__bonus:hover,
.kna-portal .kna-srs__handoff:hover,
.kna-portal .kna-srs__revive:hover,
.kna-portal .kna-srs__leech-aside:hover,
.kna-portal .kna-srs__practice-start:hover,
.kna-portal .kna-srs__practice-end:hover,
.kna-portal .kna-srs__next:hover {
	border-color: var(--kna-ink);
	background: var(--kna-surface);
	color: var(--kna-ink);
}

/* "Dalej" in practice mode stands where the reveal button stands, on cream. */
.kna-portal .kna-srs__next {
	margin: 22px 18px 0;
	width: auto;
}

.kna-portal .kna-srs__practice-end {
	margin: 10px 18px 20px;
	width: auto;
	font-size: 12.5px;
	min-height: 40px;
}

/*
 * The leech offer. Sits under the card, quiet, and only when a word has
 * actually earned it - an option, not a verdict.
 */
.kna-portal .kna-srs__leech {
	margin: 0 18px;
	padding: 14px 0 0;
	border-top: 1px dashed var(--kna-line-control);
	text-align: left;
}

.kna-portal .kna-srs__leech-note {
	margin: 0 0 10px;
	font-size: 12.5px;
	line-height: 1.45;
	color: var(--kna-ink-soft);
}

/* The daily-allowance note on /konto, under the headline count. */
.kna-account .kna-account__due-note {
	display: block;
	margin-top: 0.25rem;
	font-size: 0.85rem;
	color: var(--kna-ink-soft);
}

.kna-account .kna-srs__handoff {
	align-self: stretch;
	min-height: 44px;
	text-decoration: none;
}

/* Reset ------------------------------------------------------------------

   A two-step inline confirm rather than window.confirm(): the native dialog
   is suppressed in some embedded contexts, cannot be styled and cannot be
   tested. The destructive button is deliberately NOT the accent colour here -
   the accent is now the friendly yellow of "Pokaż odpowiedź", and a
   confirm-delete wearing it would be the worst possible signal. */

.kna-portal .kna-srs__reset {
	margin-top: 4px;
	padding-top: 14px;
	border-top: 1px solid var(--kna-cream-line);
}

.kna-portal .kna-srs__reset-start {
	padding: 0;
	border: 0;
	background: none;
	font-family: var(--kna-font-body);
	font-size: 12.5px;
	color: var(--kna-ink-muted);
	text-decoration: underline;
	text-underline-offset: 3px;
	cursor: pointer;
	min-height: 32px;
	transition: color var(--kna-ease);
}

.kna-portal .kna-srs__reset-start:hover,
.kna-portal .kna-srs__reset-start:focus-visible {
	color: var(--kna-danger);
}

.kna-portal .kna-srs__reset-confirm {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 8px;
	width: 100%;
}

.kna-portal .kna-srs__reset-warning {
	flex-basis: 100%;
	font-weight: var(--kna-weight-bold);
	color: var(--kna-ink);
}

.kna-portal .kna-srs__reset-yes {
	flex: 1 1 auto;
	min-height: 44px;
	padding: 12px 18px;
	background: var(--kna-danger);
	border: 1px solid var(--kna-danger);
	border-radius: 999px;
	color: #fff;
	font-family: var(--kna-font-body);
	font-size: 13.5px;
	font-weight: var(--kna-weight-medium);
	line-height: 1;
}

.kna-portal .kna-srs__reset-no {
	flex: 1 1 auto;
	min-height: 44px;
	padding: 12px 18px;
	background: var(--kna-surface);
	border: 1px solid var(--kna-cream-line);
	border-radius: 999px;
	color: var(--kna-ink);
	font-family: var(--kna-font-body);
	font-size: 13.5px;
	font-weight: var(--kna-weight-medium);
	line-height: 1;
}

.kna-portal .kna-srs__reset-yes[disabled],
.kna-portal .kna-srs__reset-no[disabled] {
	opacity: 0.55;
	cursor: progress;
}

/* Extra practice ---------------------------------------------------------

   Marked on the root so the whole module can read as a different mode, and
   so nothing has to guess from the presence of the grade buttons. */

.kna-portal .kna-srs-root.is-practice .kna-srs__stage {
	background: var(--kna-panel);
}

.kna-portal .kna-srs-root.is-practice .kna-srs__side-label {
	color: var(--kna-ink-muted);
}

/* --------------------------------------------------------------- player -- */

/*
 * The MINI transport, re-skinned over patron-portal.css's version. Only the
 * differences are here - the play/pause glyph, the loading state and the flex
 * layout all still come from there, and the yellow it paints the play button
 * arrives on its own because --kna-accent is redeclared at the top of this file.
 *
 * These win on load order, not specificity: both selectors are 0,2,0 and this
 * stylesheet is enqueued with patron-portal.css as a dependency.
 */
.kna-hub .kna-secure-player {
	margin: 16px;
	padding: 22px 18px 16px;
	background: var(--kna-cream);
	border-radius: var(--kna-radius-panel);
}

.kna-hub .kna-secure-player__controls {
	gap: 14px;
}

/*
 * SIZE IS SET FOUR WAYS ON PURPOSE.
 *
 * patron-portal.css gives every transport button `min-width: 44px; min-height:
 * 44px`, and a min- wins over a plain width/height however specific the rule
 * that set them. Overriding only width/height left the buttons 38px wide and
 * 44px tall on desktop - ovals, not circles - so min-* has to be restated
 * everywhere the size changes.
 */
.kna-hub .kna-secure-player__controls button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	line-height: 1;
	width: 44px;
	min-width: 44px;
	height: 44px;
	min-height: 44px;
	padding: 0;
	background: var(--kna-surface);
	border: 1px solid var(--kna-cream-edge);
	color: var(--kna-ink-soft);
	font-family: var(--kna-font-body);
	font-size: 11.5px;
	font-weight: var(--kna-weight-medium);
	transition: border-color var(--kna-ease), color var(--kna-ease);
}

.kna-hub .kna-secure-player__controls button:hover:not([disabled]) {
	border-color: var(--kna-ink);
	color: var(--kna-ink);
}

/* The one filled control in the card, and the only shadow on it. */
.kna-hub .kna-secure-player__controls button.kna-secure-player__play {
	width: 56px;
	min-width: 56px;
	height: 56px;
	min-height: 56px;
	box-shadow: var(--kna-shadow-key);
}

.kna-hub .kna-secure-player__play:hover:not([disabled]) {
	border-color: var(--kna-accent) !important;
}

.kna-hub .kna-secure-player__timeline {
	gap: 10px;
	margin-top: 18px;
	font-size: 12px;
	font-weight: var(--kna-weight-medium);
	color: var(--kna-ink-soft);
}

/*
 * The scrubber. `accent-color` cannot express a cream track with a black
 * handle, so both are drawn explicitly - and because the vendor pseudo-elements
 * cannot be combined into one selector list (a browser drops the whole rule on
 * an unrecognised selector), the track and thumb rules are repeated per engine.
 *
 * The input keeps its 44px height for the hit area; the visible track is 5px
 * inside it.
 */
.kna-hub .kna-secure-player__seek {
	-webkit-appearance: none;
	appearance: none;
	height: 44px;
	background: transparent;
}

.kna-hub .kna-secure-player__seek::-webkit-slider-runnable-track {
	height: 5px;
	border-radius: 3px;
	background: var(--kna-cream-track);
}

.kna-hub .kna-secure-player__seek::-moz-range-track {
	height: 5px;
	border-radius: 3px;
	background: var(--kna-cream-track);
}

.kna-hub .kna-secure-player__seek::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: 13px;
	height: 13px;
	/* Centres a 13px handle on a 5px track. */
	margin-top: -4px;
	border: 0;
	border-radius: 50%;
	background: var(--kna-ink);
}

.kna-hub .kna-secure-player__seek::-moz-range-thumb {
	width: 13px;
	height: 13px;
	border: 0;
	border-radius: 50%;
	background: var(--kna-ink);
}

.kna-hub .kna-secure-player__status {
	margin: 10px 0 0;
	font-size: 12.5px;
	color: var(--kna-ink-soft);
}

/*
 * The locked shell shown to anyone below the 10 zl tier.
 *
 * NOT IN THE DESIGN - derived. It keeps the transport's exact shape, because
 * showing what you would get is the entire job of this element, and drops only
 * the yellow: a grey play button on cream reads as "not yours yet", where the
 * old greyscale-and-fade read as "failed to load". It carries no data-post-id,
 * so nothing is bound to it and its controls are already disabled.
 */
.kna-hub .kna-secure-player--locked {
	background: var(--kna-panel);
	pointer-events: none;
}

.kna-hub .kna-secure-player--locked .kna-secure-player__controls button {
	background: var(--kna-surface);
	border-color: var(--kna-line-control);
	color: var(--kna-ink-faint);
}

.kna-hub .kna-secure-player--locked .kna-secure-player__controls button.kna-secure-player__play {
	background: var(--kna-line-control) !important;
	border-color: var(--kna-line-control) !important;
	box-shadow: none;
}

.kna-hub .kna-secure-player--locked .kna-secure-player__icon-play {
	border-left-color: var(--kna-surface);
}

.kna-hub .kna-secure-player--locked .kna-secure-player__timeline {
	color: var(--kna-ink-faint);
}

.kna-hub .kna-secure-player--locked .kna-secure-player__seek::-webkit-slider-runnable-track {
	background: var(--kna-track);
}

.kna-hub .kna-secure-player--locked .kna-secure-player__seek::-moz-range-track {
	background: var(--kna-track);
}

.kna-hub .kna-secure-player--locked .kna-secure-player__seek::-webkit-slider-thumb {
	background: var(--kna-dot-idle);
}

.kna-hub .kna-secure-player--locked .kna-secure-player__seek::-moz-range-thumb {
	background: var(--kna-dot-idle);
}

/* -------------------------------------------------------------- paywall -- */

/*
 * Also derived. The upgrade prompt is the one moment in a locked module where
 * something SHOULD be pressed, so it gets the zone's only filled pill - the same
 * one the flashcard's reveal uses - on the same cream that means "patron" every
 * other place it appears.
 */
.kna-hub .kna-paywall {
	padding: 20px 18px;
	background: var(--kna-cream);
	border-radius: var(--kna-radius-panel);
	text-align: center;
}

.kna-hub .kna-paywall__heading {
	margin: 0 0 6px;
	font-family: var(--kna-font-display);
	font-size: 17px;
	line-height: 1.25;
	font-weight: var(--kna-weight-bold);
	letter-spacing: -0.01em;
	color: var(--kna-ink);
}

.kna-hub .kna-paywall__body {
	margin: 0 0 16px;
	font-size: 13.5px;
	line-height: 1.5;
	color: var(--kna-ink-soft);
	text-wrap: pretty;
}

.kna-hub .kna-paywall__cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: 14px 30px;
	background: var(--kna-accent);
	border: 0;
	border-radius: 999px;
	color: var(--kna-ink);
	font-family: var(--kna-font-body);
	font-size: 15px;
	font-weight: var(--kna-weight-bold);
	line-height: 1;
	text-decoration: none;
	box-shadow: var(--kna-shadow-key);
	transition: background-color var(--kna-ease);
}

.kna-hub .kna-paywall__cta:hover,
.kna-hub .kna-paywall__cta:focus-visible {
	background: var(--kna-accent-hover);
	color: var(--kna-ink);
}

/* The button reads "Wspieraj"; this says where it lands, for screen readers. */
.kna-hub .kna-paywall__cta-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ----------------------------------------------------------- responsive -- */

/*
 * Four grades in a row rather than 2x2. Below this the buttons would be too
 * narrow for "Znowu / 1 min" to sit on two lines without wrapping the label
 * itself, which is why the breakpoint is here and not at the layout one.
 */
@media (min-width: 35em) {

	.kna-portal .kna-srs__grades,
	.kna-portal .kna-srs__skeleton-grid {
		grid-template-columns: repeat(4, 1fr);
	}

	.kna-portal .kna-srs {
		min-height: 21rem;
	}

	.kna-portal .kna-srs__reveal,
	.kna-portal .kna-srs__round-next {
		width: auto;
		min-width: 220px;
		padding: 14px 30px;
	}

	.kna-portal .kna-srs__bonus,
	.kna-portal .kna-srs__handoff,
	.kna-portal .kna-srs__revive,
	.kna-portal .kna-srs__practice-start,
	.kna-portal .kna-srs__leech-aside {
		width: auto;
	}

	/* Disclosure left, Quizlet right, once there is width for both. */
	.kna-portal .kna-srs__footer {
		flex-direction: row;
		align-items: flex-start;
		justify-content: space-between;
		gap: 26px;
	}

	.kna-hub .kna-hub__quizlet {
		flex: none;
		padding: 9px 15px;
	}
}

/*
 * The two-column layout. Below this the trainer and the player stack, which is
 * also the phone layout - there is no third arrangement.
 */
@media (min-width: 56.25em) {

	.kna-hub {
		padding: 56px 0 64px;
	}

	.kna-hub .kna-hub__inner {
		padding: 38px 16px 0;
		gap: 34px;
	}

	.kna-hub .kna-hub__zone {
		gap: 34px;
	}

	.kna-hub .kna-hub__body {
		grid-template-columns: 1.55fr 1fr;
		gap: 28px;
	}

	/* Type steps up ------------------------------------------------------ */

	/* The mark is one size at every width, as the theme's badge is. */
	.kna-hub .kna-hub__heading-row {
		gap: 12px;
		margin-bottom: 10px;
	}

	.kna-hub .kna-hub__title {
		padding: 10px 24px 10px 16px;
		border-radius: 14px;
		gap: 12px;
		font-size: 38px;
		line-height: 1.08;
	}

	.kna-hub .kna-hub__lede {
		font-size: 15.5px;
		line-height: 1.55;
	}

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

	.kna-hub .kna-hub__module {
		border-radius: var(--kna-radius);
	}

	/* Heading left, swap pill right, on one rule. */
	.kna-hub .kna-hub__module--cards .kna-hub__module-header {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		gap: 16px;
		padding: 22px 26px 18px;
	}

	.kna-hub .kna-hub__module-title {
		font-size: 19px;
	}

	/*
	 * Only safe to hold on one line once the card is this wide. On a phone the
	 * same string wraps rather than being clipped.
	 */
	.kna-hub .kna-hub__module-sub {
		font-size: 13px;
		white-space: nowrap;
	}

	.kna-hub .kna-hub__module-tools {
		flex: none;
	}

	.kna-portal .kna-srs__swap {
		width: auto;
		min-height: 36px;
		padding: 9px 15px;
		font-size: 13px;
	}

	/* Stats bar ---------------------------------------------------------- */

	.kna-portal .kna-srs__bar {
		gap: 26px;
		padding: 14px 26px;
	}

	.kna-portal .kna-srs__summary {
		gap: 6px 26px;
		font-size: 13px;
	}

	.kna-portal .kna-srs__bar-end {
		gap: 12px;
	}

	.kna-portal .kna-srs__status {
		font-size: 12.5px;
	}

	.kna-portal .kna-srs__track {
		width: 120px;
		height: 6px;
	}

	/* Flashcard ---------------------------------------------------------- */

	.kna-portal .kna-srs__stage,
	.kna-portal .kna-srs__done {
		padding: 42px 26px 30px;
	}

	.kna-portal .kna-srs__side-label {
		margin-bottom: 16px;
		font-size: 11.5px;
	}

	.kna-portal .kna-srs__term {
		font-size: 40px;
	}

	.kna-portal .kna-srs__answer {
		min-width: 280px;
		margin-top: 14px;
		padding-top: 14px;
	}

	.kna-portal .kna-srs__answer .kna-srs__side-label {
		margin-bottom: 6px;
	}

	.kna-portal .kna-srs__back {
		font-size: 24px;
	}

	.kna-portal .kna-srs__reveal {
		margin-top: 26px;
	}

	/* Grading ------------------------------------------------------------ */

	.kna-portal .kna-srs__grading {
		padding: 20px 26px 24px;
	}

	.kna-portal .kna-srs__grading-caption {
		margin-bottom: 12px;
		font-size: 12.5px;
	}

	.kna-portal .kna-srs__grades {
		gap: 10px;
	}

	.kna-portal .kna-srs__grade {
		min-height: 52px;
		padding: 12px 8px;
	}

	.kna-portal .kna-srs__grade-when {
		font-size: 11.5px;
	}

	/* Footer ------------------------------------------------------------- */

	.kna-portal .kna-srs__footer {
		margin: 0 26px;
		padding: 16px 0 24px;
	}

	.kna-portal .kna-srs__leech {
		margin: 0 26px;
	}

	.kna-portal .kna-srs__noscript {
		margin: 16px 26px 0;
	}

	/* MINI --------------------------------------------------------------- */

	.kna-hub .kna-hub__module--mini .kna-hub__module-header {
		padding: 22px 24px 0;
	}

	.kna-hub .kna-hub__module--mini .kna-hub__module-title {
		font-size: 18px;
	}

	.kna-hub .kna-hub__module-icon {
		width: 24px;
		height: 24px;
		padding: 3px;
	}

	.kna-hub .kna-hub__module-body {
		padding: 8px 24px 0;
	}

	.kna-hub .kna-secure-player {
		margin: 0 16px 18px;
	}

	.kna-hub .kna-secure-player__controls button {
		width: 38px;
		min-width: 38px;
		height: 38px;
		min-height: 38px;
	}

	.kna-hub .kna-secure-player__controls button.kna-secure-player__play {
		width: 58px;
		min-width: 58px;
		height: 58px;
		min-height: 58px;
	}

	.kna-hub .kna-hub__locked,
	.kna-hub .kna-hub__pending {
		margin-left: 0;
		margin-right: 0;
		padding-left: 24px;
		padding-right: 24px;
	}

	.kna-hub .kna-hub__pending {
		margin: 16px 24px;
		padding: 22px 18px;
	}

}

/* ====================================================== account page ==== */

/*
 * The learner dashboard, to design_handoff_konto.
 *
 * It shares the token block at the top of this file with .kna-hub, which is why
 * almost nothing here names a colour: the two surfaces are one system, and the
 * trainer that appears on both is literally the same component. What differs is
 * configuration, not styling - see the compact-trainer note further down.
 *
 * WIDTH IS NOT SET HERE. The dashboard is injected inside the theme's `.account`
 * wrapper, which is already a centred 815px column, so it lines up with the
 * settings rows below by construction. Setting our own max-width would be a
 * copy of the theme's number, left to drift the first time the theme changed.
 */

.kna-account {
	padding: 0 0 40px;
	color: var(--kna-ink);
	font-family: var(--kna-font-body);
}

.kna-account .kna-account__inner {
	max-width: none;
	margin: 0;
	padding: 0;
}

/* Greeting and section heading ------------------------------------------- */

/*
 * Sits under the page's own h1. The name is the only bold thing in it: the
 * sentence is a greeting, not a status readout, and bolding the counts too
 * would make it read as a dashboard row.
 */
.kna-account .kna-account__greeting {
	margin: 6px 0 34px;
	font-size: 14.5px;
	line-height: 1.55;
	color: var(--kna-ink-soft);
	text-wrap: pretty;
}

.kna-account .kna-account__greeting strong {
	font-weight: var(--kna-weight-bold);
	color: var(--kna-ink);
}

.kna-account .kna-account__section-title {
	margin: 0 0 14px;
	font-family: var(--kna-font-display);
	font-size: 18px;
	line-height: 1.25;
	font-weight: var(--kna-weight-bold);
	letter-spacing: -0.01em;
	color: var(--kna-ink);
}

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

/*
 * Same frame as the lesson zone's modules, and for the same reason: the bands
 * inside run edge to edge, so the card carries no padding of its own and
 * `overflow: hidden` keeps them inside the corner.
 */
.kna-account .kna-account__card {
	margin: 0 0 14px;
	padding: 0;
	background: var(--kna-surface);
	border: 1px solid var(--kna-border);
	border-radius: var(--kna-radius-card-sm);
	overflow: hidden;
}

.kna-account .kna-account__card-header {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 12px;
	padding: 18px 18px 14px;
	border-bottom: 1px solid var(--kna-line-inner);
}

.kna-account .kna-account__card-heading {
	min-width: 0;
}

.kna-account .kna-account__title {
	margin: 0;
	font-family: var(--kna-font-display);
	font-size: 17px;
	line-height: 1.25;
	font-weight: var(--kna-weight-bold);
	letter-spacing: -0.01em;
	color: var(--kna-ink);
}

.kna-account .kna-account__card-sub {
	margin: 3px 0 0;
	font-size: 12.5px;
	line-height: 1.4;
	color: var(--kna-ink-muted);
}

/* --------------------------------------------------------- card A: review -- */

/*
 * THE COMPACT TRAINER.
 *
 * Card A and the lesson page's "Trener słownictwa" are one component in two
 * configurations, exactly as the handoff asks. Everything below is arrangement,
 * not restyling - the flashcard, the grades, the swap pill and the done screen
 * all arrive already dressed from the .kna-hub rules, because both surfaces now
 * share the token block.
 *
 * Two differences, both driven by there being no single lesson here:
 *   - the per-deck stats bar is suppressed (srs-view.js already hides the
 *     summary in global mode - "Umiem 4" has no meaning across every lesson);
 *   - what remains of the bar is moved BELOW the card, as the progress footer
 *     the design puts there.
 */
.kna-account .kna-srs {
	display: flex;
	flex-direction: column;
	padding: 0;
	background: transparent;
	border-radius: 0;
	text-align: left;
	min-height: 0;
}

.kna-account .kna-srs:focus {
	outline: none;
}

/* The bar carries only the round counter here, so it becomes the footer. */
.kna-account .kna-srs__bar {
	order: 99;
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 12px 18px;
	background: var(--kna-surface-alt);

	/* Inherited from the component, where this band sits ABOVE the card. */
	border-bottom: 0;
	border-top: 1px solid var(--kna-line-inner);
}

.kna-account .kna-srs__summary {
	display: none;
}

.kna-account .kna-srs__bar-end {
	display: flex;
	align-items: center;
	gap: 12px;
	width: 100%;
	flex-direction: row-reverse;
}

/* Track first, then the words - the design reads left to right that way. */
.kna-account .kna-srs__track {
	flex: 1 1 auto;
	width: auto;
	height: 6px;
	border-radius: 3px;
	background: var(--kna-track);
	overflow: hidden;
}

.kna-account .kna-srs__status {
	flex: none;
	margin: 0;
	font-size: 12.5px;
	color: var(--kna-ink-faint);
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

/*
 * The direction is shown on the pill in the header, so it comes off the screen
 * here exactly as it does on the lesson page - but stays in the live region,
 * which is the only thing that announces a swap.
 */
.kna-account .kna-srs__dir-note {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.kna-account .kna-account__card-tools:empty {
	display: none;
}

/*
 * The card sits in a 815px column rather than the lesson page's wider left
 * track, so the flashcard steps down from the lesson's 40px term. Everything
 * else about it - the cream, the dashed rule, the gold side labels, the yellow
 * reveal - comes from the component and is deliberately not repeated here.
 */
.kna-account .kna-srs__term {
	font-size: 28px;
}

.kna-account .kna-srs__stage {
	padding: 32px 18px 26px;
}

/* Nothing due: stands where the flashcard would, on the same cream. */
.kna-account .kna-account__empty {
	padding: 32px 18px;
	background: var(--kna-cream);
	text-align: center;
}

.kna-account .kna-account__empty-title {
	margin: 0 0 6px;
	font-family: var(--kna-font-display);
	font-size: 17px;
	font-weight: var(--kna-weight-bold);
	letter-spacing: -0.01em;
	color: var(--kna-ink);
}

.kna-account .kna-account__empty-note {
	margin: 0;
	font-size: 13.5px;
	line-height: 1.5;
	color: var(--kna-ink-soft);
}

/* Explains why today's number is smaller than the pile. Quiet, above the card. */
.kna-account .kna-account__due-note {
	margin: 0;
	padding: 12px 18px 0;
	font-size: 12.5px;
	line-height: 1.45;
	color: var(--kna-ink-muted);
}

/* --------------------------------------------------------- card B: resume -- */

.kna-account .kna-account__resume-body {
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding: 18px;
}

.kna-account .kna-account__thumb {
	flex: none;
	overflow: hidden;
	border-radius: var(--kna-radius-control);
	background: var(--kna-panel);
}

.kna-account .kna-account__thumb img {
	display: block;
	width: 100%;
	height: 120px;
	object-fit: cover;
}

.kna-account .kna-account__resume-text {
	min-width: 0;
}

.kna-account .kna-account__eyebrow {
	margin: 0 0 4px;
	font-size: 11px;
	font-weight: var(--kna-weight-bold);
	line-height: 1.2;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--kna-gold);
}

.kna-account .kna-account__lesson {
	margin: 0 0 5px;
	font-family: var(--kna-font-display);
	font-size: 18px;
	line-height: 1.25;
	font-weight: var(--kna-weight-bold);
	letter-spacing: -0.01em;
	color: var(--kna-ink);
}

.kna-account .kna-account__meta {
	margin: 0 0 14px;
	font-size: 13.5px;
	line-height: 1.45;
	color: var(--kna-ink-muted);
}

/* The one filled action on this page's second card. */
.kna-account .kna-account__continue {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 44px;
	padding: 13px 26px;
	background: var(--kna-accent);
	border: 0;
	border-radius: 999px;
	color: var(--kna-ink);
	font-family: var(--kna-font-body);
	font-size: 14.5px;
	font-weight: var(--kna-weight-bold);
	line-height: 1;
	text-decoration: none;
	box-shadow: var(--kna-shadow-key);
	transition: background-color var(--kna-ease);
}

.kna-account .kna-account__continue:hover,
.kna-account .kna-account__continue:focus-visible {
	background: var(--kna-accent-hover);
	color: var(--kna-ink);
}

/* Recent lessons --------------------------------------------------------- */

.kna-account .kna-account__recent {
	margin: 0;
	padding: 0 18px;
	list-style: none;
	border-top: 1px solid var(--kna-line-inner);
}

.kna-account .kna-account__recent li {
	margin: 0;
	border-bottom: 1px solid var(--kna-line-row);
}

.kna-account .kna-account__recent li:last-child {
	border-bottom: 0;
}

/*
 * The whole row is the target, not the words in it - 14.5px of text is a poor
 * thing to hit on a phone, and these rows are the page's main navigation.
 */
.kna-account .kna-account__recent-link {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	min-height: 44px;
	padding: 13px 0;
	color: var(--kna-ink);
	font-size: 14.5px;
	line-height: 1.35;
	font-weight: var(--kna-weight-medium);
	text-decoration: none;
	transition: color var(--kna-ease);
}

.kna-account .kna-account__recent-link:hover,
.kna-account .kna-account__recent-link:focus-visible {
	color: var(--kna-link-hover);
}

.kna-account .kna-account__recent-title {
	min-width: 0;
}

.kna-account .kna-account__tick {
	margin-left: 6px;
	color: var(--kna-tick);
	font-weight: var(--kna-weight-bold);
}

.kna-account .kna-account__recent-arrow {
	flex: none;
	color: var(--kna-arrow);
	transition: color var(--kna-ease);
}

.kna-account .kna-account__recent-link:hover .kna-account__recent-arrow {
	color: var(--kna-link-hover);
}

/* Card footer: the running total. */
.kna-account .kna-account__count {
	margin: 0;
	padding: 12px 18px;
	background: var(--kna-surface-alt);
	border-top: 1px solid var(--kna-line-inner);
	font-size: 12.5px;
	color: var(--kna-ink-faint);
}

/* -------------------------------------------------------- card C: patron -- */

/*
 * A strip rather than a card with bands: it holds one fact and one action, so
 * it takes the panel fill and keeps its padding.
 */
/*
 * Sits ABOVE "Twoja nauka" - it answers a different question from the two cards
 * below it, so it gets its own gap rather than reading as the first of a set.
 */
.kna-account .kna-account__patron {
	margin-bottom: 26px;
	background: var(--kna-panel);
}

/*
 * The way out to Patronite. A quiet inline link rather than a button: changing
 * tier is a thing a patron occasionally wants, not a thing this page is asking
 * them to do, and the invite pill already owns the loud version of that job for
 * everybody else.
 */
.kna-account .kna-account__manage {
	display: inline-flex;
	align-items: baseline;
	gap: 4px;
	margin-left: 2px;
	color: var(--kna-ink-soft);
	font-weight: var(--kna-weight-medium);
	text-decoration: underline;
	text-underline-offset: 3px;
	white-space: nowrap;
	transition: color var(--kna-ease);
}

.kna-account .kna-account__manage:hover,
.kna-account .kna-account__manage:focus-visible {
	color: var(--kna-link-hover);
}

.kna-account .kna-account__manage-glyph {
	font-size: 11px;
	line-height: 1;
}

.kna-account .kna-account__patron-top {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 14px;
	padding: 18px;
}

.kna-account .kna-account__badge {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin: 0;
	padding: 9px 16px;
	min-height: 34px;
	border-radius: 999px;
	background: var(--kna-accent);
	color: var(--kna-ink);
	font-size: 14px;
	font-weight: var(--kna-weight-bold);
	line-height: 1.2;
	text-decoration: none;
	white-space: nowrap;
}

/*
 * THE PATRONITE BADGE, at about four-fifths of the theme's.
 *
 * The theme draws this at 200x42 as one rung of a six-tier ladder. Here there is
 * only the learner's own tier and it shares a row with a heading, so it is
 * scaled to 34px tall - still the same object: hairline black frame, 9px corner,
 * mark, wordmark, and the level in a black block welded to the right edge.
 *
 * Not yellow. Every other badge in this system is, but this one is a borrowed
 * mark and reads as itself; making it match would make it look like ours.
 */
.kna-account .kna-account__badge--patronite {
	gap: 0;
	padding: 0;
	min-width: 168px;
	background: var(--kna-surface);
	border: 1px solid var(--kna-ink);
	border-radius: 9px;
	overflow: hidden;
}

.kna-account .kna-account__badge-mark {
	flex: none;
	width: 20px;
	height: auto;
	margin: 0 8px 0 10px;
}

.kna-account .kna-account__badge-text {
	margin-right: 8px;
	font-size: 12px;
	font-weight: var(--kna-weight-bold);
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: var(--kna-ink);
}

/*
 * min-width rather than a fixed square: the top tier is 100, and three digits in
 * a 34px box would either clip or shrink the type below the rest of the badge.
 */
.kna-account .kna-account__badge-level {
	flex: none;
	min-width: 34px;
	margin-left: auto;
	padding: 0 8px;
	align-self: stretch;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--kna-ink);
	color: var(--kna-surface);
	font-size: 14px;
	font-weight: var(--kna-weight-bold);
	line-height: 34px;
}

/* Says in one sentence what the three glyphs above say visually. */
.kna-account .kna-account__badge-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Not a patron: the same slot becomes an invitation, so the card keeps shape. */
.kna-account .kna-account__badge--invite {
	min-height: 44px;
	background: var(--kna-surface);
	border: 1px solid var(--kna-ink);
	transition: background-color var(--kna-ease), border-color var(--kna-ease);
}

.kna-account .kna-account__badge--invite:hover,
.kna-account .kna-account__badge--invite:focus-visible {
	background: var(--kna-accent);
	border-color: var(--kna-accent);
	color: var(--kna-ink);
}

.kna-account .kna-account__badge-glyph {
	font-size: 12px;
	line-height: 1;
}

/* ------------------------------------------------------ account: desktop -- */

/*
 * One breakpoint, at the content column's own width - below it the cards are
 * the full width of a phone and everything stacks.
 */
@media (min-width: 46.25em) {

	.kna-account {
		padding-bottom: 56px;
	}

	.kna-account .kna-account__greeting {
		margin-bottom: 40px;
		font-size: 15.5px;
	}

	.kna-account .kna-account__section-title {
		font-size: 20px;
	}

	.kna-account .kna-account__card {
		margin-bottom: 16px;
		border-radius: var(--kna-radius);
	}

	.kna-account .kna-account__card-header {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		gap: 16px;
		padding: 20px 24px 16px;
	}

	.kna-account .kna-account__title {
		font-size: 18px;
	}

	.kna-account .kna-account__card-sub {
		font-size: 13px;
		white-space: nowrap;
	}

	.kna-account .kna-account__card-tools {
		flex: none;
	}

	/*
	 * The component sizes this pill for a phone until 900px, but this header
	 * becomes a row at 740px - without this it would be a full-width pill sharing
	 * a line with the heading, squashing it, for that whole band of widths.
	 */
	.kna-account .kna-srs__swap {
		width: auto;
		min-height: 36px;
		padding: 9px 15px;
		font-size: 13px;
	}

	.kna-account .kna-srs__bar {
		padding: 12px 24px;
	}

	.kna-account .kna-srs__stage {
		padding: 38px 24px 30px;
	}

	.kna-account .kna-srs__term {
		font-size: 36px;
	}

	.kna-account .kna-srs__grading {
		padding: 16px 24px 20px;
	}

	.kna-account .kna-account__empty,
	.kna-account .kna-account__due-note {
		padding-left: 24px;
		padding-right: 24px;
	}

	/* Card B: thumbnail beside the text rather than above it. */
	.kna-account .kna-account__resume-body {
		flex-direction: row;
		align-items: center;
		gap: 20px;
		padding: 20px 24px;
	}

	.kna-account .kna-account__thumb {
		width: 132px;
	}

	.kna-account .kna-account__thumb img {
		height: 88px;
	}

	.kna-account .kna-account__resume-text {
		flex: 1 1 auto;
		display: flex;
		flex-direction: column;
		align-items: flex-start;
	}

	.kna-account .kna-account__lesson {
		font-size: 19px;
	}

	.kna-account .kna-account__meta {
		margin-bottom: 0;
	}

	/*
	 * The CTA leaves the text column and sits at the end of the row, which is
	 * where the design puts it and where a scanning eye expects the action.
	 */
	.kna-account .kna-account__continue {
		width: auto;
		align-self: center;
		flex: none;
		order: 3;
	}

	.kna-account .kna-account__recent {
		padding-left: 24px;
		padding-right: 24px;
	}

	.kna-account .kna-account__count {
		padding: 12px 24px;
	}

	.kna-account .kna-account__patron-top {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		padding: 20px 24px;
	}

	.kna-account .kna-account__patron {
		margin-bottom: 34px;
	}

	/* Last card in the zone now, so the gap to the settings rows is its. */
	.kna-account .kna-account__resume {
		margin-bottom: 56px;
	}
}

@media (min-width: 35em) {
	.kna-account .kna-srs__grades { grid-template-columns: repeat(4, 1fr); }
}

/* ------------------------------------------------- docked mobile player -- */

/*
 * The MINI player, following you down the lesson once you have started it.
 *
 * NO MEDIA QUERY HERE, ON PURPOSE. dock.js applies .is-stuck only below its own
 * mobile breakpoint, so the width lives in exactly one place - see the note on
 * MOBILE in that file. A copy of the number here could only drift.
 *
 * NOT position: sticky. A sticky element is bounded by its parent's box and can
 * never leave it, and this player's parent is a card barely taller than the
 * player - measured in a headless browser, it scrolled away to top: -112px with
 * the class correctly applied. Fixed is bounded by the viewport instead, which
 * also means an `overflow: hidden` ancestor is irrelevant: overflow does not
 * clip fixed descendants. That is why .kna-hub__module keeps the clip its
 * edge-to-edge bands need.
 *
 * `top` is set inline by dock.js, which measures the admin bar rather than
 * assuming a width for it.
 */
.kna-hub .kna-secure-player.is-stuck {
	position: fixed;
	right: 0;
	left: 0;
	width: 100%;
	max-width: none;
	/* margin and top are set inline by dock.js - see the note there. */
	padding: 0 16px;
	border-radius: 0;
	/*
	 * One row, the same height as the episode player's bar so the two are
	 * interchangeable to look at. flex-direction is spelled out because the
	 * resting card is a column, and inheriting that is what put the episode
	 * player's controls outside its bar.
	 */
	height: 54px;
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	overflow: hidden;
	/*
	 * Below the app nav (9990) and the theme header (9999) so neither is ever
	 * covered, but high above page content: a docked bar anything in the
	 * article can paint over is worse than no bar.
	 */
	z-index: 9980;
	background: var(--kna-cream);
	border-bottom: 1px solid var(--kna-border);
	box-shadow: 0 2px 10px rgba(29, 53, 87, 0.12);
}

/*
 * The seek bar, the timestamps and the status line go; play, the two skips and
 * the rate stay. Those are the controls somebody reaches for without looking,
 * which is the whole point of it following them.
 */
.kna-hub .kna-secure-player.is-stuck .kna-secure-player__timeline,
.kna-hub .kna-secure-player.is-stuck .kna-secure-player__status {
	display: none;
}

.kna-hub .kna-secure-player.is-stuck .kna-secure-player__controls {
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	margin: 0;
	padding: 0;
}

/*
 * The play button is 56px at rest, which protrudes from a 54px bar and gets
 * sheared off by the overflow clip. Constrained here rather than in the base
 * rule, which is the size the resting card actually wants.
 */
.kna-hub .kna-secure-player.is-stuck .kna-secure-player__controls button.kna-secure-player__play {
	width: 40px;
	min-width: 40px;
	max-width: 40px;
	height: 40px;
	min-height: 40px;
	max-height: 40px;
}

/* The transport buttons keep a thumb-sized target inside the shorter bar. */
.kna-hub .kna-secure-player.is-stuck .kna-secure-player__controls button {
	width: 38px;
	min-width: 38px;
	height: 38px;
	min-height: 38px;
}

/*
 * dock.js inserts these around every player it manages. Both must be inert:
 * the sentinel is what gets measured, so it must not affect layout, and the
 * spacer is sized from script to hold the docked player's place exactly.
 */
.kna-dock-sentinel {
	height: 0;
	margin: 0;
	padding: 0;
	pointer-events: none;
}

/*
 * Transparent on purpose. It stands in for a card that has left the flow, so
 * anything it painted would be an empty coloured block sitting where the player
 * used to be.
 */
.kna-dock-spacer {
	flex: none;
	margin: 0;
	padding: 0;
	background: transparent;
	border: 0;
	box-shadow: none;
	pointer-events: none;
}
