/**
 * Daily Health Tracker — front-end styles.
 *
 * One colour drives the whole form. `--dht-accent` is printed into the
 * head by DHT_Theme, resolved from the theme customiser or Elementor's
 * global palette, and every other colour here is mixed from it. Change
 * that one value and the form re-skins.
 *
 * Nothing sets font-family. Type comes from the theme, on purpose.
 */

.dht {
	/* Printed into the head next to this file, using this same selector
	   and therefore winning on source order. The literal below is only
	   reached if that rule is stripped — by a CSS optimiser, or by this
	   stylesheet being used on its own. */
	--dht-accent: #0cbe7e;

	--dht-surface: #fff;
	--dht-muted: #6b7280;

	/* Mixed from the accent. These literals are the pre-mixed values for
	   the default accent; the @supports block below re-derives them from
	   whatever --dht-accent actually is. Custom properties accept almost
	   any token sequence, so an unsupported color-mix() would be stored
	   happily here and only collapse at the point of use — which is why
	   the fallbacks live in a separate block rather than as a second
	   declaration on the same property. */
	--dht-fill: #e7f9f2;
	--dht-fill-strong: #d3f3e7;
	--dht-ring: rgba( 12, 190, 126, .28 );
	--dht-line: #dde3e0;
	--dht-line-strong: #8fdcbc;
	--dht-ink-accent: #07764f;

	/* The yes/no pair, and only that pair. Fixed rather than mixed from
	   the accent: these two have to stay reliably green and red however
	   the form is skinned, and an accent that happened to be red would
	   otherwise draw a Yes in the No colour.

	   The weekly report card's cells read these too, so that a Yes is the
	   same green in the place it is answered and the place it is reported
	   back. That is a change of mind: these used to be the check-in
	   form's alone, on the grounds that a report should not paint a No as
	   a fault. The card is read by a coach deciding what to do next, and
	   the answer they most need to pick out of a row is the one that did
	   not happen. The charts and the rings stay on the accent and on the
	   per-habit colours — a proportion is not an answer. */
	--dht-yes-line: #16a34a;
	--dht-yes-fill: rgba( 22, 163, 74, .12 );
	--dht-yes-ink: #14532d;
	--dht-no-line: #dc2626;
	--dht-no-fill: rgba( 220, 38, 38, .10 );
	--dht-no-ink: #7f1d1d;

	/* Focus is drawn in neither of those two hues, so a keyboard user is
	   never asked to tell a green ring from a green selection. */
	--dht-focus: #1d4ed8;

	/* The space between one block of this plugin and the next. Every
	   top-level block carries .dht — the account bar, the check-in form,
	   the dashboard, the report card's frame — and nothing nested does,
	   so putting the rhythm here is what makes a third block added later
	   line up without anyone remembering to space it.

	   It is a bottom margin rather than a gap because these blocks are
	   siblings in the theme's content wrapper, which is not ours to turn
	   into a flex column. Adjacent blocks collapse 32 against 0 and get
	   32, which is the intended figure either way. */
	--dht-stack: 32px;

	/* THE MEASURE, AND WHY IT IS SET HERE
	   ----------------------------------------------------------------
	   One number, on the one class every top-level block of this plugin
	   carries. The dashboard, the report card, the account bar and the
	   check-in form are siblings in the theme's content wrapper and have
	   to line up down both edges; a width set per component is a set of
	   numbers that drift apart the first time one of them is touched.

	   This is deliberately not scoped to the profile page. "Every plugin
	   block on the front end is this wide" is a rule somebody can hold in
	   their head; "the profile is wide and the form is narrow" is two
	   rules and an exception.

	   FRONT END ONLY. This stylesheet is registered and enqueued by
	   DHT_Form alone, which runs on shortcode output — it never loads in
	   wp-admin, and no element in wp-admin carries .dht in any case. The
	   report card sets no width of its own precisely so that the surface
	   decides, and in wp-admin the surface is still the content column.

	   width rather than max-width, so the gutter subtracts from the
	   measure instead of being added outside it. min() gives the smaller
	   of the two, so below 1080 + gutters the block simply becomes the
	   viewport less its margins, and there is never a horizontal
	   scrollbar. .dht is border-box, so a block that draws a border and
	   padding — .dht-box, the card frame — stays inside the same edges as
	   one that does not. */
	--dht-measure: 1080px;
	--dht-gutter: 20px;

	width: min( var( --dht-measure ), 100% - var( --dht-gutter ) * 2 );
	margin: 0 auto var( --dht-stack );
}

/* A browser without min() gets the old behaviour rather than a full-bleed
   block: max-width caps it and the auto margins centre it, with the
   gutter coming from the theme's own content padding. */
@supports not ( width: min( 10px, 10% ) ) {

	.dht {
		width: auto;
		max-width: var( --dht-measure );
	}
}

/* Narrow screens get a smaller gutter — 20px each side of a 360px phone
   is a tenth of the screen spent on nothing. */
@media screen and ( max-width: 600px ) {

	.dht {
		--dht-gutter: 14px;
	}
}

@supports ( color: color-mix( in srgb, red 50%, white ) ) {

	.dht {
		--dht-fill: color-mix( in srgb, var( --dht-accent ) 10%, #fff );
		--dht-fill-strong: color-mix( in srgb, var( --dht-accent ) 18%, #fff );
		--dht-ring: color-mix( in srgb, var( --dht-accent ) 28%, transparent );
		--dht-line: color-mix( in srgb, var( --dht-accent ) 14%, #d9dedb );
		--dht-line-strong: color-mix( in srgb, var( --dht-accent ) 45%, #fff );

		/* Text sitting on --dht-fill-strong, darkened far enough to clear
		   4.5:1 against it whatever the accent is. */
		--dht-ink-accent: color-mix( in srgb, var( --dht-accent ) 62%, #000 );
	}
}

/* ---------- the card everything sits in ---------- */

.dht-box {
	box-sizing: border-box;
	padding: 26px 24px 24px;
	border: 1px solid var( --dht-line );
	border-radius: 16px;
	background: var( --dht-surface );
	box-shadow: 0 1px 2px rgba( 16, 24, 40, .04 ), 0 10px 30px rgba( 16, 24, 40, .05 );
}

/* ---------- signing in ---------- */

/* Narrower than the tracker itself and given room to breathe, so the card
   reads as a doorway rather than as the first of several panels. The space
   is padding rather than viewport centring, which would fight the theme's
   own header and footer. */
.dht-signin {
	max-width: 460px;
	padding: 48px 0 64px;
}

.dht-signin__card {
	padding: 48px 40px;
	border-radius: 20px;
	box-shadow: 0 1px 2px rgba( 16, 24, 40, .04 ), 0 16px 44px rgba( 16, 24, 40, .08 );
	text-align: center;
}

.dht-signin__title {
	margin: 0 0 10px;
	font-size: 23px;
	line-height: 1.3;
}

.dht-signin__text {
	margin: 0 0 28px;
	color: var( --dht-muted );
	font-size: 15px;
	line-height: 1.55;
}

.dht-signin__note {
	margin: 20px 0 0;
	color: var( --dht-muted );
	font-size: 13px;
	line-height: 1.55;
}

/* Google's identity guidelines: white button, neutral border, the mark at
   its own colours on the left. None of the accent tokens are used here on
   purpose — re-skinning the tracker must never tint the Google mark or the
   surface it sits on. */
.dht-gbtn {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12px;
	box-sizing: border-box;
	width: 100%;
	min-height: 48px;
	padding: 0 16px;
	border: 1px solid #dadce0;
	border-radius: 8px;
	background: #fff;
	color: #3c4043;
	font-size: 15px;
	font-weight: 600;
	text-decoration: none;
	transition: background-color .18s ease, border-color .18s ease, box-shadow .18s ease;
}

.dht-gbtn:hover {
	border-color: #d2e3fc;
	background: #f8faff;
	box-shadow: 0 1px 2px rgba( 60, 64, 67, .18 );
	color: #3c4043;
}

/* The focus ring may use the accent — it is the site's, not Google's. */
.dht-gbtn:focus-visible {
	outline: 2px solid var( --dht-accent );
	outline-offset: 3px;
}

.dht-gbtn__icon {
	display: flex;
	flex: 0 0 18px;
}

.dht-gbtn__icon svg {
	display: block;
	width: 18px;
	height: 18px;
}

/* ---------- notices ---------- */

.dht-note {
	margin: 0 0 18px;
	padding: 11px 15px;
	border-radius: 9px;
	background: var( --dht-fill );
	color: var( --dht-ink-accent );
	font-size: 14.5px;
}

.dht-errors {
	margin: 0 0 20px;
	padding: 13px 17px;
	border-left: 4px solid #c0392b;
	border-radius: 5px;
	background: #fdecea;
}

.dht-errors ul {
	margin: 0;
	padding-left: 18px;
}

.dht-errors li {
	margin: 3px 0;
	font-size: 15px;
}

/* ---------- one question ---------- */

/* Grouped answers are wrapped in a <fieldset> so the <legend> names them
   for a screen reader. Every visual default that comes with those two
   elements is reset here: the border framed each question a second time
   inside .dht-box, and the legend sits in a gap cut into that border,
   which is what put a rule through the heading. Questions are separated
   by space alone. */
.dht-field {
	box-sizing: border-box;
	min-width: 0; /* a fieldset defaults to min-content, which breaks flex children */
	margin: 0 0 28px;
	padding: 0;
	border: 0;
}

/* OceanWP, and several other themes, style `form legend` with a
   full-width border-bottom — which drew a rule under every question
   heading. .dht-label never declared a border, so there was nothing to
   override it with.

   Reset on the elements themselves rather than on .dht-field/.dht-label,
   so it holds regardless of what classes the markup carries. One class
   plus one type beats the theme's two types, so this wins on specificity
   without !important. */
.dht fieldset,
.dht legend {
	border: 0;
}

.dht-label {
	display: block;
	width: 100%; /* a <legend> shrink-wraps otherwise */
	float: none; /* the initial value; some engines used float to opt a legend out of its special rendering */
	margin: 0 0 16px;
	padding: 0;
	/* Same reason as .dht-choice: the theme rule that borders a legend
	   also recolours it, and a question is body copy — it should read in
	   whatever colour the theme sets for text. */
	color: inherit;
	text-align: start;
	font-weight: 600;
	line-height: 1.4;
}

.dht-unit {
	font-weight: 400;
	color: var( --dht-muted );
}

.dht-unit::before {
	content: "(";
}

.dht-unit::after {
	content: ")";
}

.dht-req {
	color: #c0392b;
}

/* ---------- typed and chosen values ---------- */

.dht-field input[type="number"],
.dht-field input[type="text"],
.dht-field select,
.dht-field textarea {
	box-sizing: border-box;
	width: 100%;
	padding: 12px 13px;
	border: 1px solid var( --dht-line );
	border-radius: 10px;
	background: var( --dht-surface );
	font-size: 16px; /* 16px stops iOS zooming the page on focus */
	line-height: 1.4;
	transition: border-color .18s ease, box-shadow .18s ease;
}

.dht-field input:focus,
.dht-field select:focus,
.dht-field textarea:focus {
	outline: none;
	border-color: var( --dht-accent );
	box-shadow: 0 0 0 3px var( --dht-ring );
}

/* ---------- choices ---------- */

.dht-choices {
	display: flex;
	flex-wrap: wrap;
	gap: 9px;
}

.dht-choice {
	position: relative;
	display: block;
	margin: 0;
	/* Inherit the theme's body colour, so no theme rule aimed at <label>
	   can grey out an option that has simply not been chosen yet. */
	color: inherit;
	cursor: pointer;
}

/* Out of sight, still in the tab order and still what the label toggles.
   Everything visible is drawn on the sibling .dht-toggle, so the checked
   state can be read with `input:checked + span` rather than :has(). */
.dht-input {
	position: absolute;
	top: 0;
	left: 0;
	width: 1px;
	height: 1px;
	margin: 0;
	padding: 0;
	opacity: 0;
	pointer-events: none;
}

.dht-toggle {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px; /* icon and label read as one centred group */
	box-sizing: border-box;
	min-height: 48px; /* tap target */
	padding: 12px 16px;
	border-radius: 10px;
	background: var( --dht-surface );
	/* The resting border is an inset shadow, not a border, so that the
	   thicker selected one costs no layout. */
	box-shadow: inset 0 0 0 1px var( --dht-line );
	font-size: 16px;
	line-height: 1.25;
	text-align: center;
	transition: background-color .18s ease, box-shadow .18s ease;
}

.dht-choice:hover .dht-toggle {
	background: var( --dht-fill );
	box-shadow: inset 0 0 0 1px var( --dht-line-strong );
}

/* Selected. This is every choice except the yes/no pair, which takes its
   own colours further down; a radio or scale answer is just an answer and
   gets nothing that reads as a verdict.

   The text colour is deliberately left alone. Darkening it here made the
   answer that had not been chosen look disabled by comparison, when it
   was only inheriting ordinary body colour. */
.dht-input:checked + .dht-toggle {
	background: var( --dht-fill-strong );
	box-shadow: inset 0 0 0 2px var( --dht-accent );
}

/* Keyboard focus, deliberately outside the button so it reads as
   something other than the selected state, which is drawn inside it. */
.dht-input:focus-visible + .dht-toggle {
	outline: 2px solid var( --dht-accent );
	outline-offset: 3px;
}

@supports not selector( :focus-visible ) {

	.dht-input:focus + .dht-toggle {
		outline: 2px solid var( --dht-accent );
		outline-offset: 3px;
	}
}

.dht-toggle__icon {
	flex: 0 0 20px;
	width: 20px;
	height: 20px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.4;
	stroke-linecap: round;
	stroke-linejoin: round;
	/* Drawn in currentColor and never dimmed, so it is always exactly the
	   colour of the label beside it. Present on both options whether or
	   not either is chosen, so selecting cannot reflow the row. */
}

/* ---------- yes / no ---------- */

.dht-choices--boolean {
	flex-wrap: nowrap; /* the pair stays side by side at every width */
	gap: 10px;
}

.dht-choices--boolean .dht-choice {
	flex: 1 1 0;
	min-width: 0;
}

/* Weight only changes where the button width is already fixed by
   flex: 1 1 0, so the heavier text cannot widen anything. */
.dht-choices--boolean .dht-input:checked + .dht-toggle {
	font-weight: 600;
}

/* Selected Yes and selected No. Tinted rather than filled, so the label
   keeps roughly 8:1 on top of it and the button still reads as a chosen
   option rather than a status banner. The border is the same inset shadow
   the resting state uses, only thicker and coloured, so selecting still
   costs no layout.

   Colour is the third signal here, never the only one. The check and the
   minus tell the two answers apart with no colour at all — both are drawn
   in currentColor, so setting `color` tints each icon to its own state
   for free — and the weight change above separates chosen from unchosen.
   That matters because these two are the common colour-blind pair, and
   because in greyscale the two tints land within a few points of each
   other: what survives desaturation is the glyph, the heavier text, and a
   2px dark border against the unselected 1px light one.

   Unselected is untouched — neutral line, body text colour, no tint — so
   before either is picked the pair still reads as two equal options
   rather than one recommendation and one warning. */
.dht-input:checked + .dht-toggle--yes {
	background: var( --dht-yes-fill );
	box-shadow: inset 0 0 0 2px var( --dht-yes-line );
	color: var( --dht-yes-ink );
}

.dht-input:checked + .dht-toggle--no {
	background: var( --dht-no-fill );
	box-shadow: inset 0 0 0 2px var( --dht-no-line );
	color: var( --dht-no-ink );
}

/* Focus keeps its shape from the shared rule — an outline, outside the
   button, where the selected border is inside it — and swaps only the
   hue, so a focused Yes is a blue ring around a green button rather than
   two greens a keyboard user has to separate. */
.dht-choices--boolean .dht-input:focus-visible + .dht-toggle {
	outline-color: var( --dht-focus );
}

@supports not selector( :focus-visible ) {

	.dht-choices--boolean .dht-input:focus + .dht-toggle {
		outline-color: var( --dht-focus );
	}
}

/* ---------- scale ---------- */

.dht-scale .dht-toggle {
	min-width: 54px;
	padding: 12px;
}

/* ---------- progress ---------- */

.dht-progress {
	margin: 18px 0 12px;
	padding: 12px 14px;
	border-radius: 10px;
	background: var( --dht-fill );
	text-align: center;
	transition: background-color .18s ease;
}

.dht-progress.is-ready {
	background: var( --dht-fill-strong );
}

.dht-progress__count {
	margin: 0;
	font-size: 15px;
	font-weight: 600;
	color: var( --dht-ink-accent );
}

.dht-progress__reason {
	margin: 4px 0 0;
	font-size: 13.5px;
	color: var( --dht-muted );
}

.dht-progress__reason:empty {
	display: none;
}

/* ---------- buttons ---------- */

.dht-btn {
	display: inline-block;
	padding: 13px 30px;
	border: 1px solid var( --dht-accent );
	border-radius: 10px;
	background: var( --dht-accent );
	color: #fff;
	font-size: 16px;
	font-weight: 600;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: opacity .18s ease;
}

.dht-btn:hover {
	opacity: .9;
	color: #fff;
}

.dht-btn:focus-visible {
	outline: 2px solid var( --dht-accent );
	outline-offset: 3px;
}

.dht-btn--ghost {
	background: transparent;
	color: var( --dht-accent );
}

.dht-btn--ghost:hover {
	background: var( --dht-fill );
	color: var( --dht-accent );
}

.dht-btn--submit {
	width: 100%;
	min-height: 52px;
	margin-top: 2px;
	padding: 15px;
}

.dht-btn:disabled,
.dht-btn:disabled:hover {
	opacity: .45;
	cursor: not-allowed;
}

/* ---------- confirmation / blocked states ---------- */

/* Same element as .dht-box, so this has to come after it to win on
   source order. */
.dht-state {
	padding: 44px 30px 40px;
	text-align: center;
}

.dht-icon {
	width: 70px;
	height: 70px;
	margin: 0 auto 20px;
	border-radius: 50%;
	background: var( --dht-fill );
	color: var( --dht-ink-accent );
	font-size: 32px;
	line-height: 70px;
}

.dht-icon--wait {
	background: rgba( 183, 122, 23, .13 );
	color: #b77a17;
}

.dht-state__title {
	margin: 0 0 11px;
}

.dht-state__text {
	margin: 0 auto 22px;
	max-width: 420px;
	color: var( --dht-muted );
}

/* ---------- daily score ---------- */

.dht-score {
	margin: 0 0 22px;
	line-height: 1.3;
}

.dht-score__value {
	display: block;
	font-size: 34px;
	font-weight: 700;
	color: var( --dht-ink-accent );
}

.dht-score__text {
	display: block;
	font-size: 14.5px;
	color: var( --dht-muted );
}

.dht-streak {
	margin: 0 0 24px;
	font-weight: 600;
	color: var( --dht-ink-accent );
}

.dht-actions {
	display: flex;
	gap: 11px;
	justify-content: center;
	flex-wrap: wrap;
}

/* ---------- summary list ---------- */

.dht-summary {
	margin: 0 0 26px;
	padding: 4px 0;
	list-style: none;
	text-align: left;
	border-top: 1px solid var( --dht-line );
}

.dht-summary li {
	display: flex;
	justify-content: space-between;
	gap: 16px;
	padding: 10px 2px;
	border-bottom: 1px solid var( --dht-line );
	font-size: 15px;
}

.dht-summary__label {
	color: var( --dht-muted );
}

.dht-summary__value {
	font-weight: 600;
	text-align: right;
}

/* ---------- filling in an earlier day ---------- */

.dht-banner {
	margin: 0 0 20px;
	padding: 14px 16px;
	border-radius: 10px;
	background: var( --dht-fill-strong );
	box-shadow: inset 0 0 0 2px var( --dht-accent );
}

.dht-banner__title {
	margin: 0;
	font-size: 16.5px;
	color: var( --dht-ink-accent );
}

.dht-banner__text {
	margin: 4px 0 0;
	font-size: 14px;
	color: var( --dht-muted );
}

/* ---------- tabs ---------- */

/* Hidden in the markup and revealed by the script. Without it both panels
   stay visible and the strip never appears, so nothing is unreachable and
   nothing is a dead control. */
.dht-tabs {
	display: flex;
	gap: 4px;
	margin: 0 0 22px;
	padding: 4px;
	border-radius: 12px;
	background: var( --dht-fill );
}

.dht-tabs__tab {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	flex: 1 1 0;
	min-height: 42px;
	padding: 8px 14px;
	border: 0;
	border-radius: 9px;
	background: transparent;
	color: var( --dht-muted );
	font-size: 15px;
	font-weight: 600;
	line-height: 1.2;
	cursor: pointer;
	transition: background-color .18s ease, color .18s ease;
}

.dht-tabs__tab:hover {
	color: var( --dht-ink-accent );
}

.dht-tabs__tab.is-active {
	background: var( --dht-surface );
	color: var( --dht-ink-accent );
	box-shadow: 0 1px 2px rgba( 16, 24, 40, .08 );
}

.dht-tabs__tab:focus-visible {
	outline: 2px solid var( --dht-accent );
	outline-offset: 2px;
}

/* The nudge. Carries its own colour so it reads at a glance from the tab
   without the tab being opened. */
.dht-tabs__count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 21px;
	height: 21px;
	padding: 0 6px;
	border-radius: 11px;
	background: var( --dht-accent );
	color: #fff;
	font-size: 12px;
	font-weight: 700;
	line-height: 1;
}

/* Only once the script has taken over may a panel be hidden. */
.dht-profile.is-tabbed .dht-panel {
	display: none;
}

.dht-profile.is-tabbed .dht-panel.is-active {
	display: block;
}

/* Without the script the two sections simply follow one another, so the
   second needs a rule to separate it. */
.dht-panel + .dht-panel {
	margin-top: 30px;
	padding-top: 26px;
	border-top: 1px solid var( --dht-line );
}

.dht-profile.is-tabbed .dht-panel + .dht-panel {
	margin-top: 0;
	padding-top: 0;
	border-top: 0;
}

.dht-panel__heading {
	margin: 0 0 14px;
	font-size: 15px;
	font-weight: 600;
	color: var( --dht-muted );
}

.dht-profile.is-tabbed .dht-panel__heading {
	/* The tab already says it. */
	display: none;
}

/* ---------- days still to fill in ---------- */

.dht-missed {
	margin: 16px 0 0;
	padding: 0;
	list-style: none;
}

.dht-missed__day {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	padding: 12px 0;
	border-top: 1px solid var( --dht-line );
}

.dht-missed__day:first-child {
	border-top: 0;
}

.dht-missed__date {
	font-weight: 600;
}

.dht-btn--small {
	padding: 9px 18px;
	font-size: 14.5px;
	white-space: nowrap;
}

/* ---------- profile ---------- */

.dht-profile__today {
	margin: 0 0 26px;
	padding: 0 0 22px;
	border-bottom: 1px solid var( --dht-line );
	text-align: center;
}

.dht-profile__state {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	margin: 0 0 6px;
	font-size: 17px;
	font-weight: 600;
}

.dht-profile__state--done {
	color: var( --dht-ink-accent );
}

.dht-profile__score {
	margin: 0 0 18px;
	font-size: 14.5px;
	color: var( --dht-muted );
}

.dht-profile__state--todo {
	margin-bottom: 18px;
}

.dht-profile__today .dht-streak {
	margin: 18px 0 0;
}

/* ---------- the account menu ---------- */

/* Its own .dht block, sitting above the card and sharing the card's
   width, so the trigger lines up with the card's right edge whatever the
   theme puts around it. */
.dht-account {
	position: relative;
	display: flex;
	justify-content: flex-end;
	margin-bottom: 14px;
}

.dht-account__trigger {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	max-width: 100%;
	padding: 6px 12px 6px 6px;
	border: 1px solid var( --dht-line );
	border-radius: 999px;
	background: var( --dht-surface );
	color: inherit;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.2;
	cursor: pointer;
	transition: border-color .18s ease, background-color .18s ease;
}

.dht-account__trigger:hover {
	border-color: var( --dht-line-strong );
	background: var( --dht-fill );
}

.dht-account__trigger:focus-visible {
	outline: 2px solid var( --dht-accent );
	outline-offset: 2px;
}

/* The initial and the photo occupy the same box. The photo is painted
   over the letter, so removing a photo that will not load reveals
   something already the right size and colour — nothing reflows and
   nothing else has to be fetched to recover. */
.dht-account__avatar {
	position: relative;
	display: block;
	flex: 0 0 32px;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	overflow: hidden;
}

.dht-account__initial {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	background: var( --dht-accent );
	color: #fff;
	font-size: 15px;
	font-weight: 700;
	line-height: 1;
	text-transform: uppercase;
}

/* Selected by element and not by the class handed to get_avatar(): a
   plugin filtering `get_avatar` replaces the whole tag, and the class
   goes with it. Ultimate Member, on this site, does exactly that. */
.dht-account__avatar img {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	object-fit: cover;
}

.dht-account__name {
	overflow: hidden;
	max-width: 12ch;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.dht-account__caret {
	flex: 0 0 12px;
	color: var( --dht-muted );
	transition: transform .18s ease;
}

.dht-account.is-open .dht-account__caret {
	transform: rotate( 180deg );
}

/* Anchored to the trigger's right edge and never wider than the viewport
   allows, so on a narrow screen it stops short of the edge instead of
   pushing the page sideways. */
.dht-account__menu {
	position: absolute;
	top: calc( 100% + 6px );
	right: 0;
	z-index: 20;
	box-sizing: border-box;
	min-width: 208px;
	max-width: calc( 100vw - 32px );
	padding: 6px;
	border: 1px solid var( --dht-line );
	border-radius: 12px;
	background: var( --dht-surface );
	box-shadow: 0 1px 2px rgba( 16, 24, 40, .05 ), 0 12px 32px rgba( 16, 24, 40, .12 );
}

.dht-account__menu[hidden] {
	display: none;
}

/* Not a menu item: it says where the plan stands and there is nothing to
   click. Kept above the links and set apart from them so it does not read
   as a disabled one. */
.dht-account__plan {
	margin: 0 0 4px;
	padding: 8px 12px 10px;
	border-bottom: 1px solid var( --dht-line );
	color: var( --dht-muted );
	font-size: 13px;
	line-height: 1.4;
}

.dht-account__item {
	display: block;
	padding: 10px 12px;
	border-radius: 8px;
	color: inherit;
	font-size: 15px;
	font-weight: 500;
	line-height: 1.3;
	text-decoration: none;
	transition: background-color .18s ease, color .18s ease;
}

.dht-account__item:hover,
.dht-account__item:focus {
	background: var( --dht-fill );
	color: var( --dht-ink-accent );
}

/* The page already being looked at.

   Deliberately not the hover fill: hover is --dht-fill, 10% of the accent,
   and this is --dht-fill-strong at 18%, so the two never read as the same
   thing. Hovering an active item keeps the stronger of the two rather than
   dropping back to the weaker one, which is why :hover and :focus are
   listed here as well.

   The bar is an inset shadow and not a border-left, so that marking an
   item active does not shunt its label 3px right of the items above and
   below it. --dht-ink-accent is the token mixed to clear 4.5:1 against
   --dht-fill-strong specifically, so the text stays legible whatever the
   accent is re-skinned to.

   Nothing here disables anything: it is still an ordinary link, because
   being on a page is not a reason to take away the way back to it. */
.dht-account__item.is-active,
.dht-account__item.is-active:hover,
.dht-account__item.is-active:focus {
	background: var( --dht-fill-strong );
	box-shadow: inset 3px 0 0 var( --dht-accent );
	color: var( --dht-ink-accent );
	font-weight: 600;
}

.dht-account__item:focus-visible {
	outline: 2px solid var( --dht-accent );
	outline-offset: -2px;
}

/* Separated from the navigation above it: leaving is a different kind of
   action from going somewhere. */
.dht-account__item--out {
	margin-top: 4px;
	padding-top: 12px;
	border-top: 1px solid var( --dht-line );
	border-radius: 0 0 8px 8px;
	color: var( --dht-muted );
}

/* ---------- mobile ---------- */

@media ( max-width: 600px ) {

	.dht-box {
		padding: 20px 16px 18px;
		border-radius: 14px;
	}

	.dht-signin {
		padding: 24px 0 40px;
	}

	.dht-signin__card {
		padding: 32px 22px;
		border-radius: 16px;
	}

	.dht-field {
		margin-bottom: 22px;
	}

	.dht-state {
		padding: 34px 18px 30px;
	}

	.dht-actions .dht-btn {
		width: 100%;
	}

	/* Still side by side — two half-width buttons beat two stacked ones
	   on a phone, and stacking would put No under the thumb's default
	   resting point. */
	.dht-choices--boolean {
		gap: 8px;
	}

	.dht-toggle {
		padding: 12px 10px;
		font-size: 15.5px;
	}

	.dht-toggle__icon {
		flex-basis: 18px;
		width: 18px;
		height: 18px;
	}

	.dht-scale .dht-toggle {
		min-width: 46px;
		padding: 12px 8px;
	}

	.dht-account {
		margin-bottom: 12px;
	}

	/* Room for a longer name on a screen that has less of it, since the
	   card beside it has already given up its own side padding. */
	.dht-account__name {
		max-width: 9ch;
	}

	.dht-account__menu {
		min-width: 190px;
		max-width: calc( 100vw - 24px );
	}
}

/* ---------- reduced motion ---------- */

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

	.dht,
	.dht *,
	.dht *::before,
	.dht *::after {
		transition: none !important;
	}
}

/* ---------- contact details on a plan notice ---------- */

.dht-contact {
	padding: 12px 16px;
	border-radius: 10px;
	background: var( --dht-fill );
	color: inherit;
	font-size: 15px;
}

/* A day outside every plan. Deliberately quieter than a missed one — it
   is not a lapse, and should not draw the eye like one. */

/* A day still to come. Like an off-plan day, it is not a lapse. */

@media ( max-width: 600px ) {

	.dht-missed__day {
		flex-wrap: wrap;
		gap: 8px;
	}

	.dht-missed__day .dht-btn--small {
		width: 100%;
	}
}
