/*
    PL Admin - styles that belong to the application rather than the design.

    pladmin.css is the design system, lifted from DT Admin's Webflow export and
    ours to maintain now (there is no Webflow version of this console); this
    file covers the console's own pieces and the Prepper Life brand.
*/

/* ------------------------------------------------------------ brand shades */

/*
    The Prepper Life colours (Tony, 2026-10-12: "use the logo & colors from
    the webflow site"), from prepper.life's own variables, laid onto the
    design's five families, 1 lightest to 10 darkest. Every theme token is
    built on these ramps, so replacing the values here carries the colour
    through buttons, tags, focus rings and the rest without touching any of
    them. The named shades are the site's; the rest are stepped between them.

        primary    7 prepper-green #3f5f31   6 heading-green #557a45
                   9 forest-green  #1f3516  10 dark-forest-green #102407
        accent     3 recommended-green #ccdbad   4 highlight-green #a4c266
                   6 olive #6b911c
        cta        5 hunter-orange #ff7300   7 link-orange #b04f00
        secondary  the site's near-blacks, tinted to its greens

    Neutral keeps the design's warm greys. Declared on :root, which is where
    pladmin.css declares them too, and this file is linked after it, so these
    win on order rather than on specificity.
*/
:root {
	--_brand---primary--primary-1:  #eef4ea;
	--_brand---primary--primary-2:  #d7e5cf;
	--_brand---primary--primary-3:  #b5d0a6;
	--_brand---primary--primary-4:  #8fb27c;
	--_brand---primary--primary-5:  #6e955c;
	--_brand---primary--primary-6:  #557a45;
	--_brand---primary--primary-7:  #3f5f31;
	--_brand---primary--primary-8:  #2f4a24;
	--_brand---primary--primary-9:  #1f3516;
	--_brand---primary--primary-10: #102407;

	/* The solid one, which --_theme---brand--primary resolves to and the
	   buttons and tags paint with. */
	--_brand---primary--primary: #3f5f31;
	--_brand---primary--primary-overlay: #3f5f3126;

	--_brand---accent--accent-1:  #f4f8e8;
	--_brand---accent--accent-2:  #e4efc9;
	--_brand---accent--accent-3:  #ccdbad;
	--_brand---accent--accent-4:  #a4c266;
	--_brand---accent--accent-5:  #86a83d;
	--_brand---accent--accent-6:  #6b911c;
	--_brand---accent--accent-7:  #587a15;
	--_brand---accent--accent-8:  #45600f;
	--_brand---accent--accent-9:  #33480a;
	--_brand---accent--accent-10: #213005;
	--_brand---accent--accent: #a4c266;
	--_brand---accent--accent-overlay: #a4c26633;

	--_brand---cta--cta-1:  #fff3ea;
	--_brand---cta--cta-2:  #ffe2cc;
	--_brand---cta--cta-3:  #ffc699;
	--_brand---cta--cta-4:  #ff9f55;
	--_brand---cta--cta-5:  #ff7300;
	--_brand---cta--cta-6:  #d96200;
	--_brand---cta--cta-7:  #b04f00;
	--_brand---cta--cta-8:  #8a3e00;
	--_brand---cta--cta-9:  #632c00;
	--_brand---cta--cta-10: #3d1b00;
	--_brand---cta--cta: #ff7300;
	--_brand---cta--cta-overlay: #ff730033;

	--_brand---secondary--secondary-1:  #f3f5f2;
	--_brand---secondary--secondary-2:  #e3e8e0;
	--_brand---secondary--secondary-3:  #c7d0c2;
	--_brand---secondary--secondary-4:  #9eab97;
	--_brand---secondary--secondary-5:  #74836c;
	--_brand---secondary--secondary-6:  #55634e;
	--_brand---secondary--secondary-7:  #3d4838;
	--_brand---secondary--secondary-8:  #1f2a1b;
	--_brand---secondary--secondary-9:  #141c11;
	--_brand---secondary--secondary-10: #0a0f08;
	--_brand---secondary--secondary: #1f2a1b;
	--_brand---secondary--secondary-overlay: #1f2a1b33;
}

/* ------------------------------------------------------------------- chrome */

/*
    Webflow's runtime injects its own badge into any page built from a
    webflow.io publish. The console is served from admin.prepper.life, so
    the badge has no business here. The script that adds it lives inside
    Webflow's minified runtime, so it is hidden rather than removed.
*/
.w-webflow-badge {
	display: none !important;
}

/* --------------------------------------------------------------- side list */

/*
    The side list became navigation once it held real clients, so its items are
    anchors now. These two rules only restore what the design already gives the
    div version and mark which client is open - there is no selected state in
    the design yet. Delete them when one arrives.
*/
.list-item.is-selected {
	background-color: var(--_theme---base--overlay-light-1, rgba(255, 255, 255, .06));
}

/* The client's name opens it; the row itself is no longer the link. */
.dt-list-link {
	flex: 1;
	min-width: 0;
	color: inherit;
	text-decoration: none;
}

/* The star posts a toggle, so it is a button in a form. Strip both back to
   what the design's icon expects. */
.dt-fav {
	display: flex;
	margin: 0;
}

.dt-fav button {
	display: flex;
	align-items: center;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	cursor: pointer;
}

/* ------------------------------------------------------------ edit panel */

/*
    A third column between the side list and the content. The design has no
    panel like it yet, so the layout is here; everything inside uses the
    design's own .button, .switch and .dt-* classes.
*/
/*
    The panel is always in the page and opens by widening, so opening it costs
    no navigation and nothing else on the page re-animates. The inner element
    keeps its own width so the content does not reflow while it moves.
*/
.dt-edit {
	flex-shrink: 0;
	width: 0;
	background-color: var(--_theme---base--background, #12161c);
	overflow: hidden;
	transition: width .24s cubic-bezier(.2, .8, .2, 1);
}

.dt-edit.is-open {
	width: 20rem;
	border-right: 1px solid var(--_theme---base--overlay-dark-2, rgba(0, 0, 0, .25));
	border-left: 1px solid var(--_theme---base--overlay-light-1, rgba(255, 255, 255, .06));
}

.dt-edit-inner {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	width: 20rem;
	height: 100%;
	overflow-y: auto;
}

@media (prefers-reduced-motion: reduce) {
	.dt-edit { transition: none; }
}

.dt-edit-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	min-height: 3rem;
	padding: 0 1rem;
	border-bottom: 1px solid var(--_theme---base--overlay-light-1, rgba(255, 255, 255, .06));
}

.dt-edit-close {
	padding: 0;
	border: 0;
	font: inherit;
	color: var(--_theme---text--text-muted, #8b96a5);
	background: none;
	text-decoration: none;
	cursor: pointer;
}

.dt-edit-close:hover {
	color: var(--_theme---text--text-dominent, #fff);
}

.dt-edit-body {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	padding: 1rem;
}

.dt-field {
	display: flex;
	flex-direction: column;
	gap: .375rem;
}

.dt-field-row {
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
}

/* Inputs, selects and textareas are the design's: .input, .select, .textarea
   on .w-input / .w-select, inside a .field, labelled by placeholder and
   data-label (the chrome shows the hint at the right once populated).
   The console's own .dt-input is retired (Tony, 2026-10-10). */

.dt-edit-save {
	margin-top: .5rem;
	text-align: center;
}

.dt-edit-foot {
	padding: 1rem;
	border-top: 1px solid var(--_theme---base--overlay-light-1, rgba(255, 255, 255, .06));
}

.dt-edit-delete {
	margin: 0 auto;
	cursor: pointer;
}

.dt-danger-actions .button {
	flex: 1;
	justify-content: center;
	text-align: center;
	cursor: pointer;
}

/*
    The switch's on state is driven by a Webflow interaction, which writes
    inline styles, so making it the brand blue has to outrank them. The knob
    and its movement are left to the interaction.
*/
.switch .switch-checkbox:checked ~ .switch-bg {
	background-color: var(--_theme---brand--primary) !important;
	border-color: var(--_theme---brand--primary) !important;
}

/*
    Asking before deleting, in the space the button occupied. The design has no
    destructive colour yet, so this is one - the same red the dashboard already
    uses for a failed state. Swap it for a token when the design gains one.
*/
:root {
	--dt-danger: #d03b3b;
}

[hidden] {
	display: none !important;
}

.dt-danger-ask {
	margin: 0 0 .75rem;
	font-size: .875rem;
	font-weight: 600;
	color: var(--_theme---text--text-dominent, #fff);
}

.dt-danger-actions {
	display: flex;
	gap: .5rem;
}

.button.dt-danger-go {
	background-color: var(--dt-danger);
	color: #fff;
}

.button.dt-danger-go:hover {
	filter: brightness(1.08);
}

.dt-edit-note {
	margin: .625rem 0 0;
	font-size: .75rem;
	line-height: 1.4;
	color: var(--_theme---text--text-muted, #8b96a5);
}

/* The options bar stretches its children; these should sit centred. */
.dt-edit-open,
.dt-connect {
	align-self: center;
}

button.button {
	border: 0;
	font: inherit;
	cursor: pointer;
}

/*
    The design's button is sized for a call to action: 1.1em type on .75rem by
    1.5rem of padding. That is too heavy for a toolbar or a card footer, and
    the design has no smaller size yet, so this is one. Drop it when the design
    gains a small variant.
*/
/* A card with nothing to report yet carries only its offer to connect. */
.dt-connect-wrap {
	display: flex;
	flex: 1;
	align-items: center;
	justify-content: center;
	padding: 1.25rem 0;
}

.button.dt-btn-sm {
	padding: .375rem .875rem;
	font-size: .8125rem;
	--_text---text-size: .8125rem;
	--_text---text-height: 1.2em;
}

/* ------------------------------------------------------------------ sign in */

.signin {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 100vh;
	min-height: 100dvh;
	padding: 1.5rem;
	background: var(--_theme---base--background, #12161c);
}

.signin-card {
	display: flex;
	flex-direction: column;
	width: 100%;
	max-width: 23rem;
	padding: 2rem;
	border: 1px solid var(--_theme---base--overlay-light-2, rgba(255, 255, 255, .12));
	border-radius: .75rem;
	background-image: linear-gradient(
		180deg,
		var(--_theme---base--surface, #1a1f27) 0%,
		var(--_theme---base--background, #12161c) 100%
	);
}

.signin-title {
	margin: 0;
	font-size: 1.5rem;
	font-weight: 700;
	color: var(--_theme---text--text-dominent, #fff);
}

.signin-sub {
	margin: .25rem 0 1.5rem;
	font-size: .8125rem;
	color: var(--_theme---text--text-muted, #8b96a5);
}

.signin-error {
	margin: 0 0 1rem;
	padding: .625rem .75rem;
	border: 1px solid #d03b3b;
	border-radius: .5rem;
	font-size: .8125rem;
	color: var(--_theme---text--text-dominent, #fff);
	background: rgba(208, 59, 59, .12);
}

.signin-label {
	margin-bottom: .375rem;
	font-size: .75rem;
	color: var(--_theme---text--text-muted, #8b96a5);
}

.signin-input {
	margin-bottom: 1rem;
	padding: .625rem .75rem;
	border: 1px solid var(--_theme---base--overlay-light-2, rgba(255, 255, 255, .12));
	border-radius: .5rem;
	font: inherit;
	font-size: .875rem;
	color: var(--_theme---text--text-dominent, #fff);
	background: var(--_theme---base--background, #12161c);
}

.signin-input:focus {
	outline: 2px solid var(--_brand---primary--primary, #3f8fdc);
	outline-offset: 1px;
}

/* The logo over the form, the name kept for a screen reader, and the
   design's primary submit for the button, full width (Tony, 2026-10-10). */
.signin-logo {
	display: block;
	width: 5rem;
	height: 5rem;
	margin: 0 auto .75rem;
}
.signin-card .signin-sub {
	text-align: center;
}
.signin-title.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	margin: -1px;
}
/* The submit as the guide draws it -- its own size, type and padding --
   centred under the fields with room to be a button. */
.signin-card .submit {
	margin: .75rem auto 0;
	min-width: 10rem;
	padding-left: 1.5rem;
	padding-right: 1.5rem;
}

/* ------------------------------------------------------------- page head */

/*
    The three rows every hand-maintained page opens with, drawn by
    /layout/page-head.cfm. The design supplies .shell-head, .shell-options and
    .shell-activity -- their borders, heights and the flex that pushes a left
    child away from a right one. Everything here is what goes inside them.

    Nothing below reuses a design class that the design's own script also
    drives. Borrowing .dash-view-btn and .dash-tbl for the sync health card is
    how one click came to empty it.
*/

/* The company, under the website name, when the two differ. */
.dt-page-sub {
	font-size: .75rem;
	line-height: 1.2;
	opacity: .6;
	margin-top: .1rem;
}

/*
    An icon button. Square, bordered, and the same size wherever it appears, so
    a row of them lines up with the toolbar icons on the left of the shell.
*/
.dt-iconbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2rem;
	height: 2rem;
	flex: 0 0 auto;
	padding: 0;
	border: 1px solid var(--_theme---base--overlay-light-1, rgba(255, 255, 255, .12));
	border-radius: .375rem;
	background: transparent;
	color: inherit;
	text-decoration: none;
	cursor: pointer;
	transition: background-color .15s ease, border-color .15s ease, opacity .15s ease;
}

.dt-iconbtn:hover {
	background-color: var(--_theme---base--overlay-light-1, rgba(255, 255, 255, .08));
	border-color: var(--_theme---base--overlay-light-2, rgba(255, 255, 255, .22));
}

.dt-iconbtn:focus-visible {
	outline: 2px solid var(--_theme---brand--primary, #2b78c2);
	outline-offset: 2px;
}

.dt-iconbtn[aria-disabled="true"],
.dt-iconbtn:disabled {
	opacity: .45;
	cursor: default;
}

.page-options {
	display: flex;
	align-items: center;
	gap: .5rem;
}

/* Row two. Controls on the left, what to do about it on the right. */
.dt-opt-left,
.dt-opt-right {
	display: flex;
	align-items: center;
	gap: .5rem;
	padding-top: .5rem;
	padding-bottom: .5rem;
	min-width: 0;
}

.dt-opt-right {
	justify-content: flex-end;
	flex-wrap: wrap;
	gap: .35rem 1rem;
	text-align: right;
}

/* A recommendation: what is wrong, and what to do about it. */
.dt-advice {
	display: inline-flex;
	align-items: flex-start;
	gap: .4rem;
	font-size: .8125rem;
	line-height: 1.35;
	min-width: 0;
}

.dt-advice-icon {
	display: inline-flex;
	flex: 0 0 auto;
	margin-top: .05rem;
}

.dt-advice-text strong {
	font-weight: 600;
}

.dt-advice-detail {
	opacity: .65;
}

/*
    A fact on the right of the second head row: a muted label and its value,
    the value a link when the page gave one. The sync report's website facts
    live here, beside the advice, so the body can start with the numbers.
*/
.dt-fact {
	display: inline-flex;
	align-items: baseline;
	gap: .35rem;
	font-size: .8125rem;
	line-height: 1.35;
	white-space: nowrap;
	min-width: 0;
}

.dt-fact-label {
	color: var(--_theme---text--text-muted, inherit);
	opacity: .8;
}

.dt-fact-value {
	font-weight: 600;
}

.dt-fact-value.is-fail {
	color: #e5695f;
}

a.dt-fact-value {
	color: var(--_theme---text--link, inherit);
	text-decoration: none;
}

a.dt-fact-value:hover {
	text-decoration: underline;
}

.dt-advice.is-fail .dt-advice-icon { color: #e5695f; }
.dt-advice.is-warn .dt-advice-icon { color: #d9a441; }
.dt-advice.is-ok   .dt-advice-icon { color: #3fbf63; }
.dt-advice.is-info .dt-advice-icon { opacity: .6; }

/* ---------------------------------------------------------- notifications */

/*
    Row three. Notices slide in from the right and, unless they are sticky,
    leave on their own. Sticky means "still true": the one that says a sync is
    running stays for as long as the sync is.

    The rail hides overflow so a notice on its way in or out is clipped at the
    edge rather than widening the page.
*/
.dt-notices {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .4rem;
	width: 100%;
	min-height: 1.5rem;
	padding: .25rem 1rem;
	overflow: hidden;
}

/*
    A notice reads as a status label the width of the row: the same tinted
    background and colour the pills use, so blue, green, amber and red mean
    here what they mean everywhere else.

    It starts a full row-width to the right and slides the whole way across,
    which is why the rail hides its overflow.
*/
.dt-notice {
	display: inline-flex;
	align-items: center;
	gap: .5rem;
	max-width: 100%;
	padding: .25rem .5rem .25rem .7rem;
	border: 1px solid transparent;
	border-radius: .375rem;
	font-size: .8125rem;
	line-height: 1.3;

	/*
	    It is only as wide as what it says, but it comes in from the far side
	    of the row: app.js measures the rail and puts that distance in
	    --dt-slide, so the travel is the width of the row whatever the notice
	    happens to say. The rail clips it on the way.
	*/
	opacity: 0;
	transform: translateX(var(--dt-slide, 100%));
	transition: opacity .32s ease, transform .42s cubic-bezier(.22, .61, .36, 1);
}

.dt-notice.is-in {
	opacity: 1;
	transform: translateX(0);
}

.dt-notice.is-out {
	opacity: 0;
	transform: translateX(var(--dt-slide, 100%));
}

.dt-notice-icon {
	display: inline-flex;
	flex: 0 0 auto;
}

.dt-notice-text {
	min-width: 0;
	font-weight: 600;
	overflow: visible;
	white-space: normal;   /* a long notice wraps rather than losing its end (2026-10-11) */
}

.dt-notice-close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.25rem;
	height: 1.25rem;
	flex: 0 0 auto;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: transparent;
	color: inherit;
	opacity: .55;
	cursor: pointer;
}

.dt-notice-close:hover {
	opacity: 1;
}

/* The status label colours, and blue for the ones that are only telling you. */
.dt-notice.is-info    { background: rgba(37, 161, 215, .16);  color: #5bb8e8; }
.dt-notice.is-ok      { background: rgba(10, 125, 40, .15);   color: #3fbf63; }
.dt-notice.is-warn    { background: rgba(190, 130, 0, .18);   color: #d9a441; }
.dt-notice.is-fail    { background: rgba(179, 38, 30, .18);   color: #e5695f; }
.dt-notice.is-unknown { background: rgba(128, 128, 128, .18); color: #9a9a9a; }


@media (prefers-reduced-motion: reduce) {
	.dt-notice {
		transition: none;
	}
}

/* ----------------------------------------------------------------- badges */

/*
    Badges: one family, the design's .dt-badge with a level, drawn by
    APPLICATION.fmt.badge() (components/format.cfc) wherever a standing is
    shown -- the page head, the health card, the key/value cards, every
    status column. The console's own status pill (.sync-pill, upper case,
    its own colours) was retired on 2026-10-10 in its favour.

    Two levels the design does not carry: warn in the amber the old pill
    had, which Tony preferred to the design's coral, and quiet for the
    grey of something left alone. Mirror both in Webflow when the design
    is next touched; until then these override pladmin.css.
*/
.dt-badge.dt-warn  { background-color: rgba(190, 130, 0, .18); color: #d9a441; }
.dt-badge.dt-quiet { background-color: rgba(128, 128, 128, .14); color: var(--colors--ink-2, inherit); }

/* ------------------------------------------------------- progress button */

/*
    The run button doubles as the progress bar for the run it starts. The fill
    is a layer behind the icon whose width is set from the poll, so the icon
    never moves and the control stays the same size throughout.
*/
.dt-runbtn {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

.dt-runbtn .dt-runbtn-fill {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: var(--dt-progress, 0%);
	background: rgba(37, 161, 215, .35);
	transition: width .6s ease;
	z-index: -1;
}

.dt-runbtn.is-running {
	border-color: var(--_theme---brand--primary, #2b78c2);
}

/*
    A running button is still disabled, so a second press cannot start a
    second run, but it is not unavailable -- it is the thing doing the work,
    and the fill across it is the point. The shared disabled rule dimmed it to
    .45, which made the one control that was busy look like the one that could
    not be used.
*/
.dt-runbtn.is-running:disabled,
.dt-runbtn.is-running[aria-disabled="true"] {
	opacity: 1;
}

/* Running, but we do not yet know how far: a slow sweep rather than a lie. */
.dt-runbtn.is-running.is-indeterminate .dt-runbtn-fill {
	width: 35%;
	animation: dt-runbtn-sweep 1.6s ease-in-out infinite;
}

@keyframes dt-runbtn-sweep {
	0%   { transform: translateX(-100%); }
	100% { transform: translateX(300%); }
}

.dt-runbtn.is-running .lucide-refresh-cw {
	animation: dt-spin 2.4s linear infinite;
}

@keyframes dt-spin {
	to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
	.dt-runbtn .dt-runbtn-fill,
	.dt-runbtn.is-running .lucide-refresh-cw {
		animation: none;
		transition: none;
	}
}

/* ------------------------------------------------- resizable side panel */

/*
    The grab strip over the top border of the Inactive label, injected by
    app.js. Ten pixels tall and centred on the border, so it answers to a
    pointer five pixels either side of it, and invisible: the border the
    design already draws is the thing being grabbed.
*/
.shell-list-title.dt-resize-host {
	position: relative;
}

.dt-resize-handle {
	position: absolute;
	top: -5px;
	left: 0;
	right: 0;
	height: 10px;
	cursor: ns-resize;
	z-index: 3;
	touch-action: none;
}

/*
    Held on the body for the length of the drag. Without it the cursor flickers
    back to a caret the moment the pointer leaves the ten pixel strip, which it
    does immediately, and the drag looks like it has stopped when it has not.
*/
body.dt-resizing,
body.dt-resizing * {
	cursor: ns-resize !important;
	user-select: none !important;
}

/* ------------------------------------------------------------- KPI line */

/*
    The line on a dashboard KPI card. Drawn server side as a plain polyline by
    components/dashboard.cfc, so the card arrives complete rather than
    appearing and then growing a chart.

    The design gives .dash-kpi-spark its height; this only makes the drawing
    fill it and take the accent colour.
*/
.dt-spark {
	color: var(--_brand---primary--primary-7);
}

.dt-spark-svg {
	display: block;
	width: 100%;
	height: 100%;
	overflow: visible;
}

/* ------------------------------------------------------- KPI card title */

/*
    The design's KPI label is small and muted, which reads as a caption under
    a number rather than the name of the thing being counted. These are the
    only four real figures on the dashboard, so the name carries its weight
    and the figure takes the brand colour.
*/
.dash-kpi .dash-kpi-label {
	font-size: .9375rem;
	font-weight: 650;
	line-height: 1.2;
	opacity: 1;
	color: inherit;
}

.dash-kpi .dash-kpi-value {
	color: var(--_brand---primary--primary-3);
}

/* --------------------------------------------------------- primary nav */

/*
    A toolbar item. The design generated one class per item it happened to
    have -- .icon-clients, .icon-workflows and so on, all with identical
    declarations -- which runs out as soon as the console has more routes
    than the design did. One class for all of them instead.

    /layout/nav.cfm builds the menu; layout/chrome/chrome-top.cfm includes it
    in place of the design's own shell-menu.
*/
.dt-nav-icon {
	opacity: .7;
	cursor: pointer;
	justify-content: center;
	align-items: center;
	min-height: 3rem;
	transition: opacity .2s;
	display: flex;
	position: relative;
}

.dt-nav-icon:hover {
	opacity: 1;
}

/* Listed so the order is settled, but there is nothing behind it yet. */
.dt-nav-icon.is-soon {
	opacity: .3;
	cursor: default;
}

/* ---------------------------------------------------------- switches */

/*
    The knob is moved by the design itself. The custom-switch stylesheet in
    layout/chrome/chrome-bottom.cfm, which every page includes, slides
    .switch-dot from left 3px to left 19px when the checkbox is checked, and
    the design's own .switch-dot rule transitions it. Nothing here moves it.

    There were rules here that did: a 3px margin and a 16px translate on
    checked, written when the dot was believed not to travel outside a
    Webflow page. Added to the design's 19px they put the knob 16px past the
    end of the track, over whatever label came next -- the Websites page's
    location switches, the Data page's verticals. Removed 2026-10-08.
*/

@media (prefers-reduced-motion: reduce) {
	.switch .switch-dot {
		transition: none;
	}
}

/* ------------------------------------------------- locations included */

/*
    One row per location, switch first so the column of them reads down the
    page as a set of states rather than a list of names.
*/
.dt-locations {
	display: flex;
	flex-direction: column;
	gap: .5rem;
	margin-top: .5rem;
}

.dt-location {
	display: flex;
	align-items: center;
	gap: .75rem;
}

.dt-location-switch {
	flex: 0 0 auto;
	margin: 0;
}

.dt-location-name {
	font-size: .875rem;
}

.dt-locations-save {
	margin-top: .5rem;
}

/*
    Webflow's .w-checkbox indents its label by 20px to make room for the
    native checkbox it replaces, and adds a bottom margin. The switch hides
    its input entirely, so that indent has nothing to make room for -- it
    just eats the 42px track and pushes the dot out over the name beside it.
*/
.switch.w-checkbox {
	box-sizing: border-box;
	flex: 0 0 42px;
	padding-left: 0;
	margin-bottom: 0;
}

/* -------------------------------------------------------- small button */

/*
    Used by the sync report, the dashboard's health card and the Websites
    page. It was defined in the first two pages' own style blocks, so the
    third rendered it as unstyled text.
*/
.sync-health-btn {
	display: inline-block;
	padding: .25rem .75rem;
	border: 1px solid var(--grid, rgba(128, 128, 128, .35));
	border-radius: 999px;
	background: transparent;
	color: inherit;
	font-size: .8125rem;
	text-decoration: none;
	cursor: pointer;
}

.sync-health-btn:hover {
	background: var(--_theme---base--overlay-light-1, rgba(128, 128, 128, .12));
}

.sync-health-btn.is-busy {
	opacity: .5;
	pointer-events: none;
}

.sync-health-btn.is-fix {
	border-color: rgba(63, 191, 99, .5);
	color: #3fbf63;
}

/*
    A return to the same page -- the range strip, a star, a save -- starts
    with the side list already open (app.js takes the collapse class off
    before first paint) and no transition on it, so nothing slides. The
    class is set by app.js from the referrer.
*/
html.is-return .shell-list,
html.is-return .shell-list.collapse { transition: none; }


/*
    Users. The picture above the account details, round, as Gravatar gives
    it; and the Access card's rows, a feature on the left and its switch on
    the right, the Save in the card bar.
*/
.dt-avatar {
	display: flex;
	justify-content: center;
	padding: 1.25rem 0 .75rem;
}

.dt-avatar img {
	width: 6rem;
	height: 6rem;
	/* Flat on top with the corners eased, a half circle below: the two
	   bottom radii at half the box in both directions make the bottom a
	   true semicircle (Tony, 2026-10-10). */
	border-radius: .75rem .75rem 50% 50%;
	border: 2px solid var(--_theme---base--overlay-light-2, rgba(255, 255, 255, .12));
	background-color: var(--_theme---base--overlay-dark-1);
	object-fit: cover;
}

.dt-row.dt-access-row {
	grid-template-columns: minmax(0, 1fr) 4rem 4rem;
	min-width: 0;
}

/* The Read and Write headings over the two columns of switches. */
.dt-access-head {
	text-align: center;
}
.dt-access-row .dt-location-switch {
	justify-self: center;
}

.dt-access-row .dt-location-switch {
	margin: 0;
}

.dt-access-note {
	margin: .75rem 0 0;
}

.dt-card-bar > .dt-iconbtn,
.dt-card-bar > .dt-feeds-nav {
	margin-left: auto;
}

/* --------------------------------------------------------- dropdowns */

/*
    The design's .options dropdown, two colours corrected here rather than
    in the generated stylesheet, which is Webflow's to regenerate. Tony,
    2026-10-09: the open list is a shade darker than the page, but the label
    over it is transparent, so a line shows where the two cross; and the
    chosen option lit in the CTA orange, where the primary colour belongs;
    and (2026-10-10) the option under the pointer lit in the form focus
    colour, which is the same orange. Mirror these in Webflow when the
    design is next touched.
*/
.options .option-label {
	background-color: var(--_theme---base--background);
}
.options .option.selected,
.options .option:hover {
	background-color: var(--_theme---brand--primary);
}

/* ------------------------------------------- side lists and type rails */

/*
    Shared by every two-panel page -- Data, Settings: the list head's tools
    and filter box (layout/pages/list-head.cfm) and the rail of types
    (layout/pages/type-rail.cfm). Moved here from app-data.css when Settings
    took the same shape.
*/
.dt-list-tools {
	display: flex;
	align-items: center;
	gap: .5rem;
}
.dt-list-new {
	display: flex;
	color: inherit;
	font: inherit;
	text-decoration: none;
}
button.dt-list-new {
	line-height: 0;
}

/* The filter box lies over the head row rather than under it, so the list
   keeps the design's measurements: the Active panel is sized to the
   viewport less the chrome, and a row added to the chrome would open a
   gap. The head is already position: relative. */
.dt-list-search {
	position: absolute;
	inset: .75rem 3.5rem .75rem .75rem;   /* covers the title and the plus; stops short of the search button, which opens and closes it */
	z-index: 6;   /* above the design's .icon, which sits at 5, so the plus never shows through */
	display: flex;
	align-items: center;
	background-color: var(--_theme---base--background, #12161c);
}
.dt-list-search .input {
	flex: 1;
	min-width: 0;
	padding: .375rem .5rem;
	font-size: .8125rem;
	background-color: var(--_theme---base--background, #12161c);   /* opaque, so nothing shows through */
}


.dt-type-rail {
	display: flex;
	flex-flow: column;
	flex-shrink: 0;
	width: 11rem;
	border-left: 1px solid var(--_theme---base--overlay-light-1);
	border-right: 1px solid var(--_theme---base--overlay-dark-2);
}
/* The design's list body spreads its children to the ends; the rail has
   only its items, and they belong at the top. */
.dt-type-rail .shell-list-body {
	justify-content: flex-start;
}
.dt-type-items {
	padding: 1rem .5rem;
}
.dt-type-item {
	display: flex;
	align-items: center;
	gap: .5rem;
	padding: .3rem .5rem;
	color: inherit;
	text-decoration: none;
}
.dt-type-item svg {
	flex: none;
	opacity: .8;
}
.dt-type-item .truncate {
	flex: 1;
	min-width: 0;
}
.dt-type-count {
	font-size: .75rem;
	color: var(--_theme---text--text-muted);
}
.dt-type-item.is-soon {
	opacity: .45;
	cursor: default;
}

/* A model's make, after its name in the Models list. */
.dt-list-sub {
	font-size: .75rem;
	color: var(--_theme---text--text-muted);
}

/* The models list's plus with no make open: present, faded, not a link. */
.dt-list-new.is-soon {
	opacity: .45;
	cursor: default;
}



/* ---------------------------------------------------------- settings gear */

/*
    The gear's flyout label sits 3rem from the gear's left edge, as every
    menu item's does -- but the design centres the gear as a box only as
    wide as its icon, with a right margin, where the menu's items stretch
    the toolbar's width. So the label landed to the right of the others.
    Stretched and unmargined, the gear is laid out as a menu item is, and
    its label lines up. The icon itself stays centred by the item's own
    flex rules. Custom hover icons, when they come, drop into the same
    box: nothing here depends on the artwork.
*/
.shell-settings .icon-settings,
.shell-menu-account .icon-account {
	align-self: stretch;
	margin-right: 0;
}

/* Their flyout labels take the CTA border, where the menu's take the
   primary (Tony, 2026-10-10): the colour the two icons light in. */
.shell-settings .menu-name,
.shell-menu-account .menu-name {
	border-color: var(--_theme---brand--cta);
}

/*
    The mask that comes on while the pointer is in the toolbar (app.js). The
    design's overlay is the side list's width, 15rem from the toolbar's
    edge, which on Data and Settings covers the rail and four rem of the
    list. With a rail it spans the rail alone, and the rail and the list
    when the list is open.
*/
.shell:has(.dt-type-rail) .shell-menu-overlay {
	width: 11rem;
}
.shell:has(.dt-type-rail):has(.shell-list:not(.collapse)) .shell-menu-overlay {
	width: 26rem;
}

/*
    A password box that is not a password box until it is focused.

    Chrome fills a saved sign-in into any text box that sits beside a
    password box, whatever the box holds and whatever autocomplete says:
    the Users edit panel showed "tony" as every administrator's username.
    So the password box is rendered as a text box, masked by CSS, and
    becomes a real password box only when it is focused; with no password
    box on the page at load, there is no sign-in form to fill.
*/
.dt-secret {
	-webkit-text-security: disc;
}

/*
    A read-only input keeps the design's look. Webflow's base sheet paints a
    read-only or disabled .w-input light grey, which on the dark theme is a
    white box: the owner's username, and every username box the moment the
    page loads (it starts read-only against autofill). The design's own
    background is restored; a field that is fixed for good (.dt-fixed) also
    reads muted and says so in its title.
*/
.input.w-input[readonly],
.select.w-select[disabled] {
	background-color: var(--colors--clear);
	background-image: linear-gradient(180deg, var(--_forms---background-1), var(--_forms---background-2));
	cursor: text;
}
.input.dt-fixed[readonly] {
	color: var(--_theme---text--text-muted);
	cursor: not-allowed;
}

/* ----------------------------------------------------------- feeds card */

/*
    The Feeds card on a client's page: a feed per row with its type under
    its name; Add and Report in the card bar; the Add form laid over the
    card's body (Tony, 2026-10-10). The card is the design's .dt-stat, made
    the containing box for the overlay.
*/
.dt-stat.dt-feeds {
	position: relative;
}
.dt-feeds-nav {
	display: flex;
	align-items: center;
	gap: .375rem;
}
.dt-feeds-empty {
	padding: 1.75rem 0;
	text-align: center;
	color: var(--_theme---text--text-muted);
}
/* The feed's name bold, its type under it on the design's small faded
   text (Tony, 2026-10-10). */
.dt-feed-name .dt-key {
	font-weight: 700;
}
.dt-feed-type {
	display: block;
}
.dt-feed-run {
	justify-self: start;
}
/* The Add panel takes the card's content area below the bar: in the
   card's own flow rather than laid over it, with no background, so the
   card bleeds through and the design's spacing classes on it -- .my-sm
   at the moment -- measure from the bar and the card's edge as they would
   anywhere (Tony, 2026-10-10). While it is open the card's own content is
   taken out of the flow, so the card is the panel's height. */
.dt-feeds-add {
	display: flex;
	flex-direction: column;
	gap: .75rem;
	background: none;
}
[data-feeds]:has(> .dt-feeds-add:not([hidden])) > :not(.dt-card-bar):not(.dt-feeds-add) {
	display: none;
}
.dt-feeds-add[hidden] {
	display: none;
}
.dt-feeds-add .field,
.dt-feeds-add .options {
	width: 100%;
}
.dt-feeds-add-actions {
	display: flex;
	gap: .5rem;
	justify-content: flex-end;
}

/* ------------------------------------------------------ navigation icons */

/*
    The primary navigation's icons move on hover, each in its own way (Tony,
    2026-10-10). The drawings are in components/icons.cfc, Lucide's with their
    parts classed; the fills here are the design's accent colour, and the
    beaker's bubble its vivid tint. Settings and Profile are the design's own
    icons and keep their motion, in the CTA colour. Every animation
    runs once on hover and holds its last frame until the pointer leaves,
    when the icon returns to its line drawing.
*/
.dt-nav-icon .nav-svg [class^="nd-"],
.dt-nav-icon .nav-svg [class*=" nd-"],
.dt-nav-icon .nav-svg .nc-front,
.dt-nav-icon .nav-svg .nw-fill,
.dt-nav-icon .nav-svg .ndt-band,
.dt-nav-icon .nav-svg .ns-band,
.dt-nav-icon .nav-svg .np-start,
.dt-nav-icon .nav-svg .np-end,
.dt-nav-icon .nav-svg .np-dot,
.dt-nav-icon .nav-svg .nt-liquid {
	fill: var(--_theme---brand--accent);
	fill-opacity: 0;
}
.dt-nav-icon .nav-svg .nt-bubble {
	fill: var(--_theme---brand--accent-vivid);
	fill-opacity: 0;
}

/* Dashboard: the two small panes light, then the two tall ones in their
   place, and again; it rests with the tall ones lit. */
.dt-nav-icon:hover .nav-dashboard .nd-small { animation: nd-small 2s linear forwards; }
.dt-nav-icon:hover .nav-dashboard .nd-tall  { animation: nd-tall  2s linear forwards; }
@keyframes nd-small { 0% { fill-opacity: 0; } 8% { fill-opacity: .85; } 22% { fill-opacity: .85; } 30% { fill-opacity: 0; } 50% { fill-opacity: 0; } 58% { fill-opacity: .85; } 72% { fill-opacity: .85; } 80% { fill-opacity: 0; } 100% { fill-opacity: 0; } }
@keyframes nd-tall  { 0%, 25% { fill-opacity: 0; } 33% { fill-opacity: .85; } 47% { fill-opacity: .85; } 55% { fill-opacity: 0; } 75% { fill-opacity: 0; } 83% { fill-opacity: .85; } 100% { fill-opacity: .85; } }

/* Clients: the person in front lights. */
.dt-nav-icon .nav-clients .nc-front { transition: fill-opacity .3s ease; }
.dt-nav-icon:hover .nav-clients .nc-front { fill-opacity: .85; }

/* Websites: the header and the left sidebar fill. */
.dt-nav-icon .nav-websites .nw-fill { transition: fill-opacity .45s ease; }
.dt-nav-icon:hover .nav-websites .nw-fill { fill-opacity: .8; }

/* Data: the bottom band fills and fades, then the middle, then the top,
   twice over; the third time the bottom two fill and stay. */
.dt-nav-icon:hover .nav-data .ndt-bottom { animation: ndt-bottom 4.5s linear forwards; }
.dt-nav-icon:hover .nav-data .ndt-middle { animation: ndt-middle 4.5s linear forwards; }
.dt-nav-icon:hover .nav-data .ndt-top    { animation: ndt-top    4.5s linear forwards; }
@keyframes ndt-bottom { 0% { fill-opacity: 0; } 5.5% { fill-opacity: .8; } 11% { fill-opacity: 0; } 33.3% { fill-opacity: 0; } 38.8% { fill-opacity: .8; } 44.4% { fill-opacity: 0; } 66.7% { fill-opacity: 0; } 72.2% { fill-opacity: .8; } 100% { fill-opacity: .8; } }
@keyframes ndt-middle { 0%, 11% { fill-opacity: 0; } 16.6% { fill-opacity: .8; } 22.2% { fill-opacity: 0; } 44.4% { fill-opacity: 0; } 50% { fill-opacity: .8; } 55.5% { fill-opacity: 0; } 72.2% { fill-opacity: 0; } 77.7% { fill-opacity: .8; } 100% { fill-opacity: .8; } }
@keyframes ndt-top    { 0%, 22.2% { fill-opacity: 0; } 27.7% { fill-opacity: .8; } 33.3% { fill-opacity: 0; } 55.5% { fill-opacity: 0; } 61.1% { fill-opacity: .8; } 66.7% { fill-opacity: 0; } 100% { fill-opacity: 0; } }

/* Subscriptions: the top strip fills, sweeps off to the right as it fades
   -- inside the card, which clips it -- then fills again and stays. */
.dt-nav-icon:hover .nav-subscriptions .ns-band { animation: ns-band 1.6s ease-in-out forwards; }
@keyframes ns-band {
	0%   { fill-opacity: 0;  transform: translateX(0); }
	25%  { fill-opacity: .85; transform: translateX(0); }
	45%  { fill-opacity: 0;  transform: translateX(22px); }
	50%  { fill-opacity: 0;  transform: translateX(0); }
	80%  { fill-opacity: .85; transform: translateX(0); }
	100% { fill-opacity: .85; transform: translateX(0); }
}

/* Pipeline: the top circle fills, a dot carries the fill down the route to
   the bottom circle, which fills; a pause, and once more. */
.dt-nav-icon .nav-pipeline .np-dot { offset-path: path("M6 5h3h8.5a3.5 3.5 0 0 1 0 7h-11a3.5 3.5 0 0 0 0 7H15h3"); offset-distance: 0%; }
.dt-nav-icon:hover .nav-pipeline .np-start { animation: np-start 1.8s linear 2 forwards; }
.dt-nav-icon:hover .nav-pipeline .np-dot   { animation: np-dot   1.8s ease-in-out 2 forwards; }
.dt-nav-icon:hover .nav-pipeline .np-end   { animation: np-end   1.8s linear 2 forwards; }
@keyframes np-start { 0% { fill-opacity: 0; } 12% { fill-opacity: .9; } 28% { fill-opacity: .9; } 36% { fill-opacity: 0; } 100% { fill-opacity: 0; } }
@keyframes np-dot   { 0%, 28% { offset-distance: 0%; fill-opacity: 0; } 30% { fill-opacity: .9; } 68% { offset-distance: 100%; fill-opacity: .9; } 72%, 100% { offset-distance: 100%; fill-opacity: 0; } }
@keyframes np-end   { 0%, 66% { fill-opacity: 0; } 72% { fill-opacity: .9; } 100% { fill-opacity: .9; } }

/* Tests: the liquid rises from the floor of the flask to the line under its
   neck, no higher; a bubble forms at its surface and is the only thing to
   rise past the line, up the neck to the mouth, where it fades. */
.dt-nav-icon .nav-tests .nt-liquid { transform: translateY(7px); }
.dt-nav-icon:hover .nav-tests .nt-liquid { animation: nt-liquid 1.9s ease-out forwards; }
.dt-nav-icon:hover .nav-tests .nt-bubble { animation: nt-bubble 2.4s ease-out forwards; }
@keyframes nt-liquid { 0% { transform: translateY(7px); fill-opacity: .8; } 60%, 100% { transform: translateY(0); fill-opacity: .8; } }
@keyframes nt-bubble { 0%, 55% { fill-opacity: 0; transform: translateY(0); } 62% { fill-opacity: 1; } 88% { fill-opacity: 1; transform: translateY(-9.5px); } 100% { fill-opacity: 0; transform: translateY(-11px); } }

/* Profile: the head and body fill in the CTA colour (Tony, 2026-10-10). */
.shell-menu-account .icon-account:hover .user-head,
.shell-menu-account .icon-account:hover .user-body {
	fill: var(--_theme---brand--cta);
}

/* The block under Profile was sized for an item that is not coming; the
   toolbar ends close under it now. */
.shell-menu-account {
	min-height: 0;
	padding-bottom: .75rem;
}

@media (prefers-reduced-motion: reduce) {
	.dt-nav-icon:hover .nav-svg * { animation: none; }
}

/* ------------------------------------------------------------- charts */

/*
    The chart row on Subscriptions. The design's .dash is what scopes the
    chart colours, and it pads itself as a page body does; here it sits
    inside one already.
*/
.dt-sub-charts {
	padding: 0;
}

/* ------------------------------------------- settings gear and profile */

/*
    The gear turns and takes the CTA colour on hover; its centre holds
    still and keeps its colour. The profile's head and body fill in the
    CTA colour (Tony, 2026-10-10). Written here, over the design's own
    rules in the chrome, with the toolbar block in the selector so these
    win whatever order the stylesheets arrive in.
*/
.shell-settings .icon-settings .gear-body {
	transform-box: view-box;
	transform-origin: 12px 12px;
	transition: transform .5s cubic-bezier(.22, 1, .36, 1), stroke .3s ease;
}
.shell-settings .icon-settings:hover .gear-body {
	transform: rotate(180deg);
	stroke: var(--_theme---brand--cta);
}
.shell-settings .icon-settings .gear-center,
.shell-settings .icon-settings:hover .gear-center {
	transform: none;
	stroke: currentColor;
}

/* ------------------------------------------------- card header controls */

/*
    Every control in a card's head or bar is an icon button, the way the
    row's edit control is (Tony, 2026-10-10): the small .dt-iconbtn with the
    action's icon and a title saying what it does. No text buttons, pills or
    "View" links up there. The small size lived in app-data.css while only
    the Data page had one; it is every page's now.

    A control that switches a card between two views -- table and chart,
    errors and recent -- is .dt-viewbtn: it carries both icons, and
    aria-pressed picks which shows. As before, the icon names the view the
    press will bring, not the one showing.
*/
.dt-iconbtn.dt-iconbtn-sm {
	width: 1.5rem;
	height: 1.5rem;
}

.dt-iconbtn.is-fix {
	border-color: rgba(63, 191, 99, .5);
	color: #3fbf63;
}

.dt-viewbtn .dt-view-a,
.dt-viewbtn .dt-view-b {
	display: inline-flex;
	line-height: 0;
}
.dt-viewbtn .dt-view-b,
.dt-viewbtn[aria-pressed="true"] .dt-view-a {
	display: none;
}
.dt-viewbtn[aria-pressed="true"] .dt-view-b {
	display: inline-flex;
}

/* ------------------------------------------------- leads table, centred */

/*
    The Daily Leads by Source table: the design's card tables right-align
    their figures, which across six narrow columns of small numbers left
    each one hugging the next column's heading. Centred instead (Tony,
    2026-10-10); the Day column keeps the left edge.
*/
#sec-leads .dash-tbl .th:not(:first-child),
#sec-leads .dash-tbl .td:not(:first-child) {
	text-align: center;
	justify-content: center;
}

/* ------------------------------------------------------------ KPI row */

/*
    The KPI cards, a little taller than the design draws them (Tony,
    2026-10-10: fifteen percent), taken as a taller box for the line, so the
    drawing gains the room. Each is headed by the design's card bar with the
    title in it, as the client page's cards are, so the card keeps the
    design's one rem of padding and the border the client cards have: the
    bar's own margins and corners are cut to those.

    The System Health card is one chart of three lines -- Success, Warn,
    Fail -- in the states' colours on one scale, under a row of the states'
    badges with their counts.
*/
.dash-kpi {
	padding: 1rem;
	border-color: var(--_theme---base--overlay-light-2);
}
.dash-kpi .dash-kpi-spark {
	height: 60px;
}

.dt-health-legend {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: .375rem .75rem;
	font-size: .875rem;
	font-variant-numeric: tabular-nums;
}
.dt-health-legend span {
	display: inline-flex;
	align-items: center;
	gap: .375rem;
}
.dt-health-legend b {
	color: var(--fg);
}
.dt-health-chart {
	margin-top: auto;
	height: 60px;
}
.dt-health-chart .is-ok   { color: #3fbf63; }
.dt-health-chart .is-warn { color: #d9a441; }
.dt-health-chart .is-fail { color: #e5695f; }

/* ---------------------------------------------------------- range strip */

/*
    The dashboard's range strip: the pressed window in the primary colour
    rather than the design's light overlay (Tony, 2026-10-10). The page's
    own stylesheet, which sets the overlay, is linked after this one, so
    the strip is in the selector to outweigh it. Mirror in Webflow when the
    design is next touched.
*/
.dash-seg .dash-seg-btn[aria-pressed="true"] {
	background: var(--_theme---brand--primary);
	color: #fff;
}

/* ------------------------------------------------- card tables, uncapped */

/*
    A chart card's table view takes the whole card rather than scrolling in
    a 380px box inside it, which left the card's lower half empty beside a
    scrollbar (Tony, 2026-10-10). The card grows to its rows.
*/
.dash-card .dash-tbl {
	max-height: none;
	overflow: visible;
}

/* ------------------------------------------------- subscriptions donuts */

/*
    The Subscriptions by Plan card: two donuts side by side, subscriptions by
    kind and MRR by kind, each captioned under it, with one key for both
    beneath (Tony, 2026-10-10).
*/
.dt-donuts {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: .5rem;
}
.dt-donut {
	text-align: center;
}
.dt-donut .dash-chart {
	min-height: 0;
}
.dt-donut .dash-sub {
	margin: .25rem 0 0;
}
.dash-card.is-table .dt-donuts {
	display: none;
}

/* ------------------------------------------------------ secondary scale */

/*
    The secondary shade family re-based (Tony, 2026-10-10): the secondary is
    the primary's darkest shade, primary-10 above, and sits at step 6 as the
    primary's own solid does. The other nine step away from it on the
    primary ramp's own ladder -- the same hue, the same saturation per step,
    and each step's lightness the same share of the room above or below the
    base that the primary's steps take -- so the two families read at the
    same pace.

    Declared on :root after the primary, for the same reason. Mirror these
    in the Webflow variable collection when the design is next touched, and
    this block goes.
*/
:root {
	--_brand---secondary--secondary-1:  #e9f3f8;
	--_brand---secondary--secondary-2:  #bdddea;
	--_brand---secondary--secondary-3:  #91c6dc;
	--_brand---secondary--secondary-4:  #3aa4d1;
	--_brand---secondary--secondary-5:  #1c6c8e;
	--_brand---secondary--secondary-6:  #005276;
	--_brand---secondary--secondary-7:  #004461;
	--_brand---secondary--secondary-8:  #003e58;
	--_brand---secondary--secondary-9:  #003850;
	--_brand---secondary--secondary-10: #002d40;

	/* The solid one, which --_theme---brand--secondary resolves to. */
	--_brand---secondary--secondary: #005276;
	--_brand---secondary--secondary-overlay: #00527626;
}

/* ------------------------------------------------ save in a card's head */

/*
    A config card's Save: the design's primary submit, in the card bar on the
    right, shown only once a switch has been flipped (Tony, 2026-10-10). The
    submit is a flex box, which the hidden attribute alone does not beat.
*/
.dt-card-bar > .submit {
	margin-left: auto;
	padding: .3rem .9rem .35rem;
}
.submit[hidden] {
	display: none;
}

/* --------------------------------------------- website health, three lines */

/*
    The website page's three health cards -- Webhook, Lead, Sync -- beside
    the info card in four equal columns, each drawn as the dashboard's
    System Health card is; Lead Health's bars of arriving leads take the
    primary (Tony, 2026-10-10).
*/
.dt-site-health-chart {
	height: 72px;
}
.dt-health-chart .dt-spark-bars.is-leads { color: var( --_brand---primary--primary ); }

/* ------------------------------------------------ feed switch labels */

/* On the website page's Feed Integrations switches the type sits to the
   right of the name (Tony, 2026-10-10); on the client's Feeds card it
   stays under it. */
.dt-location-name .dt-feed-type {
	display: inline;
	margin-left: .5rem;
}

/* --------------------------------------------- select hints, centred */

/*
    The hint a field shows at its right once it has a value is centred on
    the field, but a native select keeps Webflow's ten pixels of bottom
    margin inside its field, which puts the hint five pixels low; and the
    chrome's right offset puts it against the select's own chevron (Tony,
    2026-10-10). Lifted and moved in, for selects only.
*/
.field:has(> .select)::after {
	top: calc(50% - 5px);
	--hint-right: 2.25rem;
}

/* ------------------------------------------- website page: info, feeds */

/*
    The website page's info card: each row split one to two, as the
    design's grid-1-2 is, so the values start on one line down the card,
    left-justified (Tony, 2026-10-10), where the design's key/value row
    sizes its key per row and sets its value to the right. And on its Feed Integrations switches, the type at the right of
    the row, the name at the left.
*/
.dt-info-card .dt-row.dt-kv {
	grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
	column-gap: 1rem;
}
.dt-info-card .dt-row.dt-kv > :last-child {
	text-align: left;
	justify-self: start;
}
.dt-location-name:has(.dt-feed-type) {
	display: flex;
	flex: 1 1 auto;
	align-items: baseline;
	justify-content: space-between;
}

/* ------------------------------------------------------- form focus */

/*
    The design's form focus tokens point at the CTA colour, which is what
    bordered an open dropdown, and every focused input and select, in
    orange. Re-pointed at the primary (Tony, 2026-10-10), on :root as the
    design declares them, so this file wins on order. Mirror in Webflow
    when the design is next touched.
*/
:root {
	--_forms---focus-border-1: var(--_theme---brand--primary-vivid);
	--_forms---focus-border-2: var(--_theme---brand--primary-vivid);
	--_forms---focus:          var(--_theme---brand--primary);
}

/* ------------------------------------------------ connect buttons */

/*
    The Traffic card's Connect Analytics and Reconnect Analytics: the
    design's submit, which pads itself only a quarter rem to the sides,
    given room to read as a button on its own in the card (Tony,
    2026-10-10).
*/
.dt-connect-wrap .submit {
	padding: .45rem 1.25rem .5rem;
	text-decoration: none;
}

/* ------------------------------------------------------------ profile */

/*
    The Profile page (Tony, 2026-10-10): the sitemap of pages on the left,
    each row a link with the page's icon and a line on what it is for; and
    the profile card's bar tools -- Save, shown once a field has changed,
    beside the edit control that becomes a cancel while the form shows.
*/
.dt-sitemap-row {
	display: flex;
	align-items: center;
	gap: .75rem;
	color: inherit;
	text-decoration: none;
}
.dt-sitemap-icon {
	display: inline-flex;
	width: 1.5rem;
	justify-content: center;
	color: var(--_theme---text--text-muted);
}
.dt-sitemap-icon svg {
	width: 18px;
	height: 18px;
}
.dt-sitemap-text {
	display: flex;
	flex-direction: column;
	gap: .1rem;
	min-width: 0;
}

.dt-profile-tools {
	display: flex;
	align-items: center;
	gap: .5rem;
	margin-left: auto;
}
.dt-profile-form {
	display: flex;
	flex-direction: column;
	gap: .75rem;
	padding-top: .5rem;
}
.dt-profile-form[hidden] {
	display: none;
}

/* The design's key/value row insists on thirty-two rem and the list scrolls
   sideways for it; the sitemap's rows fit their card instead. */
.dt-sitemap .dt-row {
	min-width: 0;
}
.dt-sitemap {
	overflow-x: hidden;
}

/* ----------------------------------------------- toolbar: profile at foot */

/*
    The design keeps Profile at the foot of the toolbar by giving the
    Settings block the spare height. Without the Settings right that block is
    hidden (layout/nav.cfm) and Profile floated up under the menu; the
    account block takes the spare height itself (Tony, 2026-10-10).
*/
.shell-menu-account {
	margin-top: auto;
}

/* A dropdown hidden by its attribute stays hidden: the Add Feed panel keeps
   one manufacturer list per website and shows the chosen website's. */
.options[hidden] {
	display: none;
}

/* The Brands card's tab set -- Boats and Motors -- drawn with the website
   tabs' rules; the panes show as Webflow shows tab panes. */
.dt-brand-tabs .dt-site-tab-menu {
	margin-bottom: .25rem;
}
.dt-brand-tabs .w-tab-content {
	overflow: visible;
}

/* The open record in a side list -- a type on the rail, a make, a model, a
   client, a website, a user -- carries the primary border (Tony,
   2026-10-11), over the tint it already had. */
.list-item.is-selected {
	border-color: var(--_theme---brand--primary);
}

/* Who sells a make: a card per dealer across the top of the make's page,
   four to a row, two when the page is narrow. */
.dt-dealers {
	grid-template-columns: repeat(4, minmax(0, 1fr));
	margin-bottom: 1rem;
}
@media (max-width: 1100px) {
	.dt-dealers {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* The Brands card's Add row: the dropdown and the button side by side. */
.dt-brand-add {
	display: flex;
	align-items: center;
	gap: .5rem;
}
.dt-brand-add .field {
	flex: 1;
	min-width: 0;
	margin: 0;
}
.dt-brand-add .options {
	width: 100%;
}

/* A dealer's card on a make's page is its logo and nothing else once there
   is one: centred, kept to the card's width, never stretched. */
.dt-dealer {
	align-items: center;
	justify-content: center;
	min-height: 6rem;
	text-decoration: none;
}
.dt-dealer-logo {
	max-width: 100%;
	max-height: 4rem;
	object-fit: contain;
}
.dt-dealer-name {
	color: var(--_theme---text--text);
	text-align: center;
}
.dt-dealer.is-inactive {
	opacity: .5;
}

/* The logo on file, above the drop field in the client's edit panel. */
.dt-logo-current {
	margin: .25rem 0 .5rem;
}
.dt-logo-current img {
	max-height: 3.5rem;
	max-width: 100%;
	object-fit: contain;
}
.dt-brand-add[hidden] {
	display: none;
}
/* The Type before the make in the Add row; the make is the design's
   autosuggest, as wide as the row allows, its list scrolling past sixteen
   rows. */
.dt-brand-add .field.dt-brand-type {
	flex: 0 0 9rem;
}
.dt-brand-add .auto-suggest {
	min-width: 0;
	width: 100%;
}
.dt-brand-add .suggestions {
	max-height: 16rem;
	overflow-y: auto;
}
/* In the design the search box is laid over a table head; in the Add row it
   sits in the flow, so the row has its height and the list opens under it. */
.dt-brand-add .suggest-search {
	position: static;
}
/* The empty option the list is cloned from stays out of sight. */
.dt-brand-add .suggestions > .option:not(.rendered) {
	display: none;
}
/* The design pads the list's top so it can slide out from under the search
   box laid over it; with the box in the flow that padding is empty space. */
.dt-brand-add .suggestions {
	padding-top: 0;
	margin-top: .25rem;
	transform: none;
}

/* A Brands row is its name and its remove; while the remove asks, the
   question and its two buttons take the row's place. */
.dt-brand-row {
	display: block;
}
.dt-brand-rest {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	gap: .5rem;
}
.dt-brand-ask {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: .5rem;
}
.dt-brand-ask .dt-danger-ask {
	margin: 0;
}
.dt-brand-ask .dt-danger-actions {
	display: flex;
	gap: .375rem;
}
.dt-brand-ask[hidden],
.dt-brand-rest[hidden] {
	display: none;
}

/* The question that stands in for Save in the client's edit panel. */
.dt-edit-confirm {
	margin-top: .25rem;
}
.dt-edit-confirm[hidden],
.dt-edit-save[hidden] {
	display: none;
}

/* The kind of dealership, as its icon, at the end of a client's row in the
   side list: ship, caravan or bike, faded, named on hover. */
.dt-list-type {
	display: inline-flex;
	align-items: center;
	margin-left: auto;
	padding-left: .5rem;
	padding-right: 5px;
	color: var(--_theme---text--text-muted);
	flex: none;
}
.dt-list-type svg {
	display: block;
}

/* The whole row is the link, so it says so. */
.list-item:has(> a.dt-list-link) {
	cursor: pointer;
}

/* The row's hover colours the name, not only the name's own: the whole row
   is the link, so wherever the pointer is on it the text takes the accent. */
.list-item:hover > a.dt-list-link {
	color: var(--_theme---brand--accent);
}

/* The round add and search buttons in a side list's head take the primary
   colour on hover, everywhere (Tony, 2026-10-11). */
.new:hover {
	border-color: var(--_theme---brand--primary);
}
.dt-list-type svg + svg {
	margin-left: .25rem;
}

/*
    The side list can be widened by its right edge (Tony, 2026-10-11): the
    width is a variable on the root, kept in localStorage so every page opens
    at the same width. Three panels have grips, by name: the Taxonomy panel
    (the types rail on Data) capped at 15svw by the drag, the List panel (the
    side list) at 20svw, and the Edit panel (Add or Edit) at 25svw. The menu
    overlay that masks the list follows.
*/
.shell-list:not(.dt-type-rail):not(.collapse) {
	width: min(var(--dt-list-width, 15rem), 20svw);
}
.dt-type-rail {
	width: max(var(--dt-rail-width, 11rem), 10svw);   /* never under 10svw; capped at 15svw by the drag, not here, since 10svw and 11rem can cross on a narrow screen */
	position: relative;   /* the grip is placed against it */
}
.dt-edit {
	position: relative;
}
.dt-edit.is-open,
.dt-edit.is-open .dt-edit-inner {
	width: min(var(--dt-edit-width, 20rem), 25svw);
}
.dt-edit:not(.is-open) .dt-list-grip {
	display: none;
}
.shell-list.is-resizing,
.dt-edit.is-resizing {
	transition: none;
}
.dt-list-grip {
	position: absolute;
	top: 0;
	bottom: 0;
	right: -5px;
	width: 10px;
	cursor: ew-resize;
	z-index: 4;
	touch-action: none;
}
body.dt-resizing-x,
body.dt-resizing-x * {
	cursor: ew-resize !important;
	user-select: none !important;
}
.shell:has(.dt-type-rail):has(.shell-list:not(.collapse)) .shell-menu-overlay {
	width: calc(max(var(--dt-rail-width, 11rem), 10svw) + min(var(--dt-list-width, 15rem), 20svw));
}
/* The rows follow the list's width: the design caps a row at 14rem for the
   list's start width, which a widened list outgrows. */
.shell-list:not(.dt-type-rail) .list-item {
	max-width: none;
}

/* A group title in an edit panel -- Sells -- with a dashed rule beneath and
   room before its rows (Tony, 2026-10-11). */
.dt-group-title {
	display: block;
	padding-bottom: .375rem;
	margin-bottom: .75rem;
	border-bottom: 1px dashed var(--_theme---base--overlay-light-2);
}

/* The drop field's words sit in its vertical middle. */
.dropzone {
	justify-content: center;
}

/* A logo field (layout/pages/logo-field.cfm): the logo on file full width,
   the drop field hidden behind Replace Logo on hover (Tony, 2026-10-11). */
.dt-logo-field.has-logo:not(.is-replacing) .dropzone {
	display: none;
}
.dt-logo-field .dt-logo-current {
	position: relative;
	margin: 0;
	border-radius: var(--_corners---corner-radius, .25rem);
	overflow: hidden;
}
.dt-logo-field .dt-logo-current img {
	display: block;
	width: 100%;
	max-width: 100%;
	max-height: 10rem;
	object-fit: contain;
}
.dt-logo-replace {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	background: rgba(0, 0, 0, .6);
	color: #fff;
	font: inherit;
	font-weight: 600;
	cursor: pointer;
	opacity: 0;
	transition: opacity .15s;
}
.dt-logo-current:hover .dt-logo-replace,
.dt-logo-replace:focus-visible {
	opacity: 1;
}
.dt-logo-field.is-replacing .dt-logo-replace {
	display: none;
}

/* A logo beside the page title, inline, no taller than the title. */
.shell-head .title:has(.dt-title-logo) {
	display: flex;
	align-items: center;
	gap: .625rem;
}
.dt-title-logo {
	height: 1.2em;
	width: auto;
	max-width: 8rem;
	object-fit: contain;
	flex: none;
}

/* The overlay that masks the panels while a toolbar label shows follows the
   panels' dragged widths (Tony, 2026-10-11), borders included: the List
   panel alone, the Taxonomy panel alone, or both. */
.shell:has(.shell-list:not(.collapse)) .shell-menu-overlay {
	width: calc(min(var(--dt-list-width, 15rem), 20svw) + 2px);
}
.shell:has(.dt-type-rail) .shell-menu-overlay {
	width: calc(max(var(--dt-rail-width, 11rem), 10svw) + 2px);
}
.shell:has(.dt-type-rail):has(.shell-list:not(.dt-type-rail):not(.collapse)) .shell-menu-overlay {
	width: calc(max(var(--dt-rail-width, 11rem), 10svw) + min(var(--dt-list-width, 15rem), 20svw) + 4px);
}

/* A square image field -- the webclip -- shown at a square's size. */
.dt-logo-field.is-square .dt-logo-current img {
	width: 6rem;
	height: 6rem;
	max-height: none;
	margin: 0 auto;
	border-radius: .75rem;
}
.dt-logo-field.is-square .dt-logo-current {
	display: flex;
	justify-content: center;
}
/* The webclip beside the title, rounded as an app icon is. */
.dt-title-logo {
	border-radius: .25em;
}

/* A black logo is shown on a light ground so it can be seen. */
.dt-logo-field.is-on-light .dt-logo-current {
	background: #f4f5f7;
	padding: .5rem;
}

/* The black and white logos side by side in the brand panel. */
.dt-logo-pair {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: .5rem;
}
.dt-logo-pair .dt-logo-current img {
	max-height: 6rem;
}

/* The brand's website in the header bar: a link icon and the domain. */
.dt-site-link {
	display: inline-flex;
	align-items: center;
	gap: .375rem;
}
.dt-site-link svg {
	flex: none;
}


/* ------------------------------------------------------- content sections */

/*
    Concepts, Articles, News, Movies and Videos (2026-10-12): a record's
    picture and its writing, inside the console's .dt-card. The design has
    no card for either, so these are the console's own, in the design's
    shape -- its radius, its gaps, its theme colours -- and shown in the
    style guide's Cards section (layout/pages/styles-cards.cfm).

    .dt-media     the record's image, poster or video, filling the card
    .dt-prose     a rich text field as Webflow holds it: headings,
                  paragraphs and lists at the console's reading size
    .dt-prose-note  a quieter paragraph inside it: a concept's writing
                  instructions under each subject
*/
.dt-media {
	overflow: hidden;
	border-radius: .5rem;
	background-color: var(--_theme---base--overlay-dark-1);
}
.dt-media img,
.dt-media video {
	display: block;
	width: 100%;
	height: auto;
	max-height: 24rem;
	object-fit: cover;
}
.dt-media.is-poster img {
	object-fit: contain;
	max-height: 32rem;
}
.dt-media-none {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 12rem;
	font-size: .8125rem;
	color: var(--_theme---text--text-muted);
}

.dt-prose {
	font-size: .875rem;
	line-height: 1.6;
	color: var(--_theme---text--text);
	overflow-wrap: anywhere;
}
.dt-prose:empty {
	display: none;
}
.dt-prose > :first-child {
	margin-top: 0;
}
.dt-prose > :last-child {
	margin-bottom: 0;
}
.dt-prose h2 {
	margin: 1.5rem 0 .5rem;
	font-size: 1.125rem;
	line-height: 1.3;
}
.dt-prose h3 {
	margin: 1.25rem 0 .375rem;
	font-size: 1rem;
	line-height: 1.3;
}
.dt-prose p {
	margin: 0 0 .75rem;
}
.dt-prose ul,
.dt-prose ol {
	margin: 0 0 .75rem;
	padding-left: 1.25rem;
}
.dt-prose li {
	margin-bottom: .25rem;
}
.dt-prose-note {
	padding-left: .75rem;
	border-left: 2px solid var(--_theme---base--overlay-light-2);
	color: var(--_theme---text--text-muted);
}

/* A post from row one -- Approve, Reopen -- sits in the row as its button
   would on its own. */
.dt-inline-form {
	display: contents;
}
