/* The shared component classes: cards, buttons, chips, pills, segmented
   controls, the drill picker and the drill designer. */

/* ---- Shared components ---- */

.tj-card {
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: 18px;
	box-shadow: var(--shadow);
	padding: 20px 22px;
}

/* The dashed panel a list stands in with while it holds nothing. The base is
   the middle size; the two modifiers take it down to a note inside a column
   and up to a page-wide statement. */
.tj-empty {
	background: var(--surface);
	border: 1.5px dashed var(--line);
	border-radius: 16px;
	padding: 28px 20px;
	text-align: center;
	color: var(--muted);
	font-size: 13.5px;
}

.tj-empty-sm {
	border-radius: 14px;
	padding: 20px;
	font-size: 13px;
}

.tj-empty-lg {
	border-radius: 20px;
	padding: 38px 24px;
	font-size: 14px;
}

/* A titled panel names the state in ink and leaves the explaining to the
   muted line under it, which reads a step smaller than the panel's own size. */
.tj-empty-title {
	font-size: 20px;
	color: var(--ink);
}

.tj-empty-title + .tj-empty-lead {
	margin-top: 5px;
	font-size: 13.5px;
}

/* The administration's own top bar: the branded title on the left, the theme,
   app-crossing and sign-out controls on the right. */
.tj-admintop {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
	margin-bottom: 28px;
}

.tj-admintop h1 {
	margin: 14px 0 0;
	font-size: 46px;
	letter-spacing: 0;
}

/* The line naming the running build, at the foot of the administration. */
.tj-buildstamp {
	margin-top: 34px;
	text-align: center;
	color: var(--muted);
	font-size: 11.5px;
	opacity: .75;
}

/* A card or tile that lifts on hover — for the clickable dashboard cards. */
.tj-lift {
	transition: transform .18s ease, box-shadow .2s ease;
}

/* A drill's description on its card. */
.tj-drilldesc {
	display: block;
	font-size: 12px;
	line-height: 1.45;
	margin-top: 2px;
}

/*
 * Three lines of text, the rest clipped. Declared after the description so its
 * display wins: the clamp is inert without -webkit-box, and a display coming
 * from anywhere more specific silently switches the clipping off.
 */
.tj-clamp3 {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* One drill in the practice list: its card, and the log box it opens. */
.tj-drillrow {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/*
 * A drill list that reads two across once there is room for both cards to
 * keep their description and their thumbnail, and one across when there is
 * not. Never three: a third column leaves the description a word a line.
 *
 * The fold is asked of the list's own width rather than the window's, since
 * the same list is drawn beside a sidebar on one page and without one on
 * another — so the query goes on the picker around it.
 */
.tj-drillpicker {
	container-type: inline-size;
}

.tj-drillpicker-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 8px;
	/* An opened drill grows its own cell; its neighbour keeps its height. */
	align-items: start;
}

/*
 * Every card the same height, so the pager under them stays under the hand
 * that is stepping through the pages. What differs between one drill and the
 * next is how many of its three lines the description fills, so the picker
 * reserves all three whether or not a drill has that much to say — which
 * keeps the height honest at any width rather than pinning it to a number
 * that would only be right at one.
 */
.tj-drillpicker-grid .tj-drilldesc {
	min-height: 3lh;
}

/*
 * The drill's name and its measurable pill, kept to one line. Allowed to
 * wrap, a pill that will not fit beside a long name drops to a line of its
 * own and leaves that one card taller than the five around it; and a card
 * with no pill is shorter than one with, the pill being the taller of the
 * two. So the line never wraps, a name too long for its column ends in an
 * ellipsis, and the line holds the pill's height either way — 20px, which
 * is an 11.5px line between 3px of padding.
 */
.tj-drillhead {
	display: flex;
	align-items: center;
	gap: 8px;
	min-height: 20px;
}

.tj-drillhead > .tj-display {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

@container (min-width: 820px) {
	.tj-drillpicker-grid {
		grid-template-columns: 1fr 1fr;
	}
}

/*
 * The opened drill reads as one card that grew rather than two stacked ones.
 * The log box cannot live inside the card itself — the card is a link, and a
 * button nested in a link would swallow the tap — so the two boxes are joined
 * along their shared edge instead, and the accent ring is drawn around both.
 */
.tj-drillopen {
	gap: 0;
	border-radius: 18px;
	outline: 2px solid var(--accent);
}

.tj-drillopen > .tj-card:first-child {
	border-bottom: 0;
	border-bottom-left-radius: 0;
	border-bottom-right-radius: 0;
}

/* The rule under the meta row, dividing what the drill is from what to do
   about it. It doubles as the seam between the two boxes. */
.tj-drillopen > .tj-card + .tj-card {
	border-top: 1px solid var(--line);
	border-top-left-radius: 0;
	border-top-right-radius: 0;
}

/*
 * The log box under the rule. Its padding lives here rather than inline,
 * where it would outrank every rule above and leave the controls sitting on
 * the separator.
 */
.tj-drilllog {
	padding: 20px 16px 16px;
}

/* The card's bottom line: a pill per focus, the level as dots, the minutes. */
.tj-drillmeta {
	display: flex;
	align-items: center;
	gap: 7px;
	flex-wrap: wrap;
	margin-top: 9px;
}

.tj-lift:hover {
	transform: translateY(-3px);
	box-shadow: var(--shadow);
}

/* The court to draw on, beside the form that names what was drawn — the same
   split the walkthrough uses, and collapsing with it. */
.tj-designer-cols {
	display: grid;
	grid-template-columns: minmax(300px, 440px) minmax(0, 1fr);
	gap: 32px;
	align-items: start;
}

/* The tools the court is drawn with, over the court itself. */
.tj-designer-tools {
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
	margin-bottom: 12px;
}

/* The hint naming the next click, against undo and clear. Neither control may
   break its own label, so the row wraps and they keep to the right instead. */
.tj-designer-foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 10px;
}

.tj-designer-acts {
	display: flex;
	gap: 6px;
	margin-left: auto;
}

.tj-designer-acts .tj-btn-ghost {
	padding: 7px 14px;
	white-space: nowrap;
}

/* A step's head: what it is called, against the kind the drawing tool fixed
   and the control that drops it. Those two stay together, so a card too narrow
   to hold the line puts them on one of their own rather than splitting them —
   which the two kinds' labels, of different lengths, otherwise do differently
   from one step to the next. */
.tj-designer-stephead {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
}

.tj-designer-stephead > .tj-input {
	flex: 1;
	min-width: 160px;
	padding: 8px 12px;
	font-weight: 600;
}

.tj-designer-stepmeta {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	margin-left: auto;
}

/* The drill designer's selected step — where the next drawn path lands. */
.tj-designer-step {
	transition: border-color .15s;
}

.tj-designer-step.tj-active {
	border-color: var(--accent);
}

/* The wizard's suggestions land one after another; backwards keeps the ghost
   opacity of already-accepted cards once each entrance has played. */
.tj-suggestion {
	display: flex;
	flex-direction: column;
	border: 1px solid var(--line);
	border-radius: 16px;
	padding: 18px 20px;
	animation: tjFadeUp .4s ease backwards;
}

.tj-suggestion + .tj-suggestion {
	animation-delay: .18s;
}

.tj-suggestion + .tj-suggestion + .tj-suggestion {
	animation-delay: .36s;
}

.tj-suggestion-meta {
	color: var(--accent);
	font-size: 11.5px;
	font-weight: 700;
	margin-top: 4px;
}

/* The description takes whatever height the three cards need to match. */
.tj-suggestion-text {
	margin: 9px 0 0;
	font-size: 13px;
	line-height: 1.5;
	flex: 1;
}

.tj-suggestion-steps {
	display: flex;
	flex-direction: column;
	gap: 5px;
	margin: 12px 0 14px;
}

.tj-suggestion-step {
	display: flex;
	gap: 8px;
	align-items: baseline;
	font-size: 12.5px;
	font-weight: 600;
}

.tj-suggestion-stepno {
	flex: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 17px;
	height: 17px;
	border-radius: 50%;
	background: var(--surface2);
	font-family: 'Barlow Condensed', sans-serif;
	font-weight: 700;
	font-size: 10.5px;
	color: var(--muted);
}

/* The wizard is two screens over one form: the brief, then what came back.
   Only one is ever in the dialog, and while a round is in flight neither is —
   the three ticking slots stand in their place. */
.tj-wiz-page {
	display: flex;
	flex-direction: column;
	gap: 22px;
}

.tj-wiz-field {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

/* Which screen this is, said quietly in the corner it is read from. */
.tj-wiz-step {
	color: var(--muted);
	font-size: 11.5px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .1em;
	align-self: flex-end;
	margin-bottom: -8px;
}

.tj-wiz-chips {
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
}

.tj-wiz-level {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	height: 26px;
}

/* The two numbers are asked side by side, and stack when there is no room. */
.tj-wiz-pair {
	display: flex;
	gap: 40px;
	flex-wrap: wrap;
}

.tj-wiz-dial {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	height: 26px;
}

.tj-wiz-dialvalue {
	font-weight: 700;
	font-size: 13.5px;
	min-width: 62px;
	text-align: center;
}

/* What each screen ends on: the ask, over a rule that separates it from the
   choices it acts upon. */
.tj-wiz-foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
	border-top: 1px solid var(--line);
	padding-top: 18px;
}

.tj-wiz-foot-centred {
	justify-content: center;
}

.tj-wiz-note {
	font-size: 12px;
	flex: 1;
	min-width: 180px;
}

/* The answer's header: the way back on the left, what was asked in the
   middle, and which screen this is on the right. */
.tj-wiz-head {
	display: flex;
	align-items: baseline;
	gap: 14px;
	flex-wrap: wrap;
}

.tj-wiz-back {
	color: var(--accent);
	font-size: 13px;
	font-weight: 700;
	text-decoration: none;
}

.tj-wiz-brief {
	color: var(--muted);
	font-size: 12.5px;
	font-weight: 600;
	flex: 1;
}

.tj-wiz-head .tj-wiz-step {
	align-self: auto;
	margin-bottom: 0;
}

/* A round's three slots, whether they hold suggestions or the wait for them. */
.tj-wiz-round {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
	gap: 14px;
}

/* The wait is the browser's to show: the request that answers it is the same
   one that would have re-rendered the dialog, and it takes its time. */
.tj-wiz-waiting {
	display: none;
}

.tj-wiz-running .tj-wiz-waiting {
	display: block;
}

.tj-wiz-running .tj-wiz-page {
	display: none;
}

.tj-spin {
	width: 26px;
	height: 26px;
	border-radius: 50%;
	border: 3px solid var(--line);
	border-top-color: var(--accent);
	animation: tjSpin .8s linear infinite;
}

/* The three stand-ins tick out of phase, so the wait reads as three drills
   being worked on rather than one spinner stamped thrice. */
.tj-suggestion-empty:nth-child(2) .tj-spin {
	animation-delay: -.27s;
}

.tj-suggestion-empty:nth-child(3) .tj-spin {
	animation-delay: -.54s;
}

/* One of the three slots being worked on, in the place its card will take. */
.tj-suggestion-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 12px;
	min-height: 210px;
	border: 1.5px dashed var(--line);
	border-radius: 16px;
	padding: 30px 20px;
	text-align: center;
	color: var(--muted);
}

/* A wizard suggestion already taken into the library: kept in view for the
   round's shape, but ghosted and no longer offering its add button. */
.tj-suggestion.tj-ghost {
	opacity: .45;
}

.tj-suggestion-added {
	text-align: center;
	font-weight: 700;
	font-size: 13px;
	color: var(--muted);
	padding: 11px 0;
}

/* The designer draws both scenes and shows the one the drill is for, so the
   wall toggle costs nothing but a class. It sits on the pane rather than the
   court so it reaches the tool row too: wall practice is solo, and the coach
   is a court-side actor with nothing to do at a wall. */
.tj-designer-pane .tj-designer-wall,
.tj-designer-pane.tj-wall .tj-designer-court {
	display: none;
}

.tj-designer-pane.tj-wall .tj-designer-wall {
	display: inline;
}

.tj-designer-pane.tj-wall .tj-designer-tools [data-tool="COACH"] {
	display: none;
}

/* The question asked before a scene swap carries a drawing over or throws it
   away, tucked under the court between it and the guidance line. */
.tj-designer-ask {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	flex-wrap: wrap;
	margin-top: 10px;
	padding: 11px 14px;
	border: 1.5px solid var(--accent);
	border-radius: 14px;
	font-size: 13px;
	font-weight: 600;
}

.tj-designer-ask[hidden] {
	display: none;
}

/* The designer court's trashcan: quiet until a drag arms it, red when the
   drag hovers it and a drop would delete. */
.tj-designer-trash {
	opacity: .45;
	transition: opacity .15s;
	pointer-events: none;
}

.tj-designer-trash.tj-armed {
	opacity: .95;
}

.tj-designer-trash.tj-hot circle {
	stroke: #d43a3a;
	fill: #d43a3a;
	fill-opacity: .18;
}

.tj-designer-trash.tj-hot g {
	stroke: #d43a3a;
}

/* The step row's kind, fixed by the drawing tool that created it. */
.tj-designer-kind {
	flex: none;
	font-size: 11.5px;
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--accent);
}

.tj-designer-kind.tj-move {
	color: var(--muted);
}

/* The designer's clickable level dots. */
.tj-level-pick {
	width: 16px;
	height: 16px;
	border-radius: 50%;
	background: var(--surface2);
	transition: background .15s;
}

.tj-level-pick.tj-on {
	background: var(--accent);
}

/* The designer's − / + stepper buttons. */
.tj-step-btn {
	display: inline-grid;
	place-items: center;
	width: 26px;
	height: 26px;
	border: 1px solid var(--line);
	background: var(--surface);
	color: var(--muted);
	border-radius: 8px;
	font-size: 13px;
	text-decoration: none;
	transition: color .15s, border-color .15s;
}

.tj-step-btn:hover {
	color: var(--accent);
	border-color: var(--accent);
}

/* The measurable-goal on/off switch. */
.tj-switch {
	flex: none;
	display: inline-block;
	width: 38px;
	height: 22px;
	border-radius: 999px;
	background: var(--surface2);
	position: relative;
	transition: background .2s;
}

.tj-switch .tj-switch-knob {
	position: absolute;
	top: 2px;
	left: 2px;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 1px 4px rgba(0, 0, 0, .25);
	transition: left .2s;
}

.tj-switch.tj-on {
	background: var(--accent);
}

.tj-switch.tj-on .tj-switch-knob {
	left: 18px;
}

/* The segmented controls: the measurable goal's count/time and higher/lower
   pairs, and the admin flip that reshapes itself as a pill. The chosen side
   carries the accent, the same as every other made choice on the page. */
.tj-seg {
	display: flex;
	background: var(--surface2);
	border-radius: 10px;
	padding: 3px;
	gap: 2px;
}

.tj-seg-opt {
	flex: 1;
	border-radius: 8px;
	padding: 8px 0;
	font-weight: 600;
	font-size: 12.5px;
	text-align: center;
	text-decoration: none;
	color: var(--muted);
	transition: all .2s;
}

.tj-seg-opt.tj-active {
	background: var(--accent);
	color: var(--on-accent);
}

.tj-muted {
	color: var(--muted);
}

.tj-kicker {
	color: var(--muted);
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .1em;
}

.tj-btn, .tj-btn-ghost {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	border: none;
	border-radius: 999px;
	padding: 11px 20px;
	font-family: 'Barlow', system-ui, sans-serif;
	font-weight: 700;
	font-size: 14.5px;
	cursor: pointer;
	transition: transform .15s ease, box-shadow .15s ease;
}

.tj-btn {
	background: var(--accent);
	color: var(--on-accent);
}

.tj-btn-ghost {
	background: transparent;
	color: var(--ink);
	border: 1px solid var(--line);
}

.tj-btn:hover, .tj-btn-ghost:hover {
	transform: translateY(-1px);
}

/* A working button ghosts out and stops taking clicks until its round ends. */
.tj-btn:disabled, .tj-btn-ghost:disabled {
	opacity: .45;
	cursor: not-allowed;
	pointer-events: none;
	transform: none;
}

/* An AI trigger while the club has AI switched off: still clickable — it
   explains itself in a dialog — but visibly muted. */
.tj-ai-off {
	opacity: .45;
}

/* The PrimeFaces base sheet loads after this one; its .ui-button drops our pill
   padding to 0 and reverts the flex box, so command-button labels lose their
   height and drift off-centre. Re-assert both at a higher specificity and strip
   the inner .ui-button-text padding so the height matches the .tj-input controls
   these buttons sit beside. */
.ui-button.tj-btn,
.ui-button.tj-btn-ghost {
	display: inline-flex;
	padding: 11px 20px;
}

.ui-button.tj-btn .ui-button-text,
.ui-button.tj-btn-ghost .ui-button-text {
	padding: 0;
}

.tj-theme-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid var(--line);
	border-radius: 50%;
	background: transparent;
	color: var(--ink);
	cursor: pointer;
	transition: transform .15s ease;
}

/* The language control sits in the same row of icon buttons as the theme
   toggle, but carries a pair of flags rather than a glyph, so it widens into a
   pill to hold them. Both classes are named on purpose: the size flavors below
   set a width of their own, and a single class would lose to them. */
.tj-theme-toggle.tj-language-toggle {
	width: auto;
	padding: 0 6px;
	border-radius: 999px;
	text-decoration: none;
}

.tj-flags {
	display: inline-flex;
	align-items: center;
}

/* A shade over the 18px glyphs beside it: a flag is read by its proportions
   rather than by an outline, so it wants the room. Only a shade, though — a
   solid disc of colour already carries more weight than a line drawing does.
   Rounded off here so the artwork itself can stay square and edge to edge. */
.tj-flags .tj-flag {
	width: 20px;
	height: 20px;
	border-radius: 50%;
	overflow: hidden;
	transition: opacity .2s, filter .2s;
}

/* Enough of an overlap to read as a pair rather than as two controls, and not
   so much that either flag loses the proportions it is recognised by. */
.tj-flag + .tj-flag {
	margin-left: -8px;
}

/* The language on screen: full colour, in front of the other, and ringed. The
   ring carries no colour of its own behind it — the button is transparent in
   most of the shells but sits on a surface in the player app, so anything
   painted there would be wrong in one of them. */
.tj-flags-en .tj-flag-en,
.tj-flags-sv .tj-flag-sv {
	position: relative;
	z-index: 1;
	box-shadow: 0 0 0 1.5px var(--accent);
}

/* The one a click would bring: held back by taking its colour away rather than
   by fading it out. Transparency blends towards whatever is behind, so the
   fade that reads on the cream page leaves nothing but a smudge on the dark
   one; grey stays grey on both. All of the colour rather than most of it —
   a flag left part way there reads as a rendering fault rather than as a
   state. */
.tj-flags-en .tj-flag-sv,
.tj-flags-sv .tj-flag-en {
	opacity: .7;
	filter: grayscale(100%);
}

/* Hovering wakes it up, which is the switch previewing itself. */
.tj-language-toggle:hover .tj-flags-en .tj-flag-sv,
.tj-language-toggle:hover .tj-flags-sv .tj-flag-en {
	opacity: .9;
	filter: grayscale(20%);
}

.tj-theme-toggle:hover {
	transform: translateY(-1px);
}

.tj-theme-toggle svg {
	width: 18px;
	height: 18px;
}

.tj-theme-toggle .tj-icon-sun {
	display: none;
}

:root[data-theme='dark'] .tj-theme-toggle .tj-icon-sun {
	display: block;
}

:root[data-theme='dark'] .tj-theme-toggle .tj-icon-moon {
	display: none;
}

/* The admin bar's flavor, a size down so the row of controls sits under the
   heading rather than beside it. */
.tj-theme-small {
	width: 36px;
	height: 36px;
}

/* The player app's flavor of the toggle, sitting over the page. */
.tj-theme-float {
	width: 36px;
	height: 36px;
	background: var(--surface);
	color: var(--muted);
}

.tj-theme-float:hover {
	border-color: var(--accent);
	color: var(--accent);
}

.tj-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	border: 1px solid var(--line);
	border-radius: 999px;
	background: var(--surface);
	color: var(--ink);
	padding: 7px 14px;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
	transition: background .2s, color .2s;
}

.tj-chip.tj-active {
	background: var(--accent);
	border-color: var(--accent);
	color: var(--on-accent);
}

/* The club's own drills toggle wears the blue their cards are drawn on,
   keeping it apart from the orange category chips it sits next to. */
.tj-chip.tj-chip-club.tj-active {
	background: var(--custom-court);
	border-color: var(--custom-court);
	color: #fff;
}

/* Splits the category chips from the toggle that follows them. */
.tj-chip-split {
	align-self: stretch;
	width: 1px;
	background: var(--line);
	margin: 2px 4px;
}

.tj-pill {
	display: inline-block;
	border-radius: 999px;
	background: var(--surface2);
	color: var(--muted);
	padding: 3px 10px;
	font-size: 11.5px;
	font-weight: 700;
}

/* ---- Legal documents ---- */

/* Long prose, set for reading rather than for scanning: a measure that stops
   short of the page's full width, and headings that separate the sections
   without shouting over them. */
.tj-legal {
	font-size: 14.5px;
	line-height: 1.7;
	max-width: 68ch;
}

.tj-legal h2 {
	font-family: 'Barlow Condensed', 'Barlow', sans-serif;
	font-weight: 700;
	font-size: 18px;
	text-transform: uppercase;
	letter-spacing: .04em;
	margin: 28px 0 8px;
}

.tj-legal p,
.tj-legal ul {
	margin: 0 0 12px;
}

.tj-legal ul {
	padding-left: 20px;
}

.tj-legal li {
	margin-bottom: 6px;
}

.tj-legal-meta {
	color: var(--muted);
	font-size: 12.5px;
	letter-spacing: .04em;
	text-transform: uppercase;
}

/* On the page that asks for agreement the document sits in a box of its own,
   so that the button below it stays in sight while the terms are read. */
.tj-legal-scroll {
	max-height: 58vh;
	overflow-y: auto;
	padding: 18px 22px;
}

.tj-legal-actions {
	display: flex;
	align-items: center;
	gap: 18px;
	margin-top: 18px;
}
