/*
 * Plugin-shared Tailwind-flavored utility CSS
 *
 * Hand-written static stylesheet that mimics the subset of Tailwind utilities
 * used by the builder UIs (Email Signature Generator, UTM Builder, and any
 * future module that opts in). Prefixed `tw-` and scoped under .lct-tw so
 * the rules don't leak into other WP admin surfaces.
 *
 * Originally written for the Email Signature Generator builder; lifted to
 * /assets/css/ so multiple modules can share the same component primitives.
 * Some of the legacy component selectors below (.lct-section-panel,
 * .lct-template-grid, .lct-builder-3col, etc.) are esig-specific and will be
 * inert on UTM-builder pages because the markup doesn't reference them.
 *
 * Also retains the rules that were in the previous signature-builder.css
 * and are still required by the JS:
 *   - .lct-signature-preview / .lct-preview-cell display behavior
 *   - .lct-validator-mark + .lct-validator-gutter (CodeMirror integration)
 *   - .lct-preview-placeholder (in-preview empty-field hint)
 *   - .lct-generate-animate keyframe (submit-enable pulse)
 *   - .lct-row-copy positioning
 *   - .lct-pill draggable
 */

/* =========================================================================
   Scoping wrapper
   ========================================================================= */

.lct-tw,
.lct-tw * {
	box-sizing: border-box;
}

.lct-tw {
	width: 100%;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	color: #111827;
}

/* FOUC backstop for inline SVGs.

   An <svg> without explicit `width`/`height` attributes falls back to its
   `viewBox` as the intrinsic render size during the brief window before
   our targeted CSS rules (e.g. .lct-preview-download svg { width: 1.1em })
   apply. For Font-Awesome-derived icons that's 576×512 px — the user
   sees a giant icon flash during first paint.

   The proper fix is to attach `width="…" height="…"` attributes to every
   inline <svg> in the markup (done — see views/builder.php and
   signature-builder.js). This rule is the belt-and-suspenders backstop:
   any future SVG that ships without those attributes is still clamped
   to a single line-height during the unstyled window so the flash is
   invisible. Named-class rules (e.g. .lct-accordion-chevron) still win
   on specificity once the stylesheet loads, so this only takes effect
   for the FOUC moment and for SVGs that genuinely have no other sizing
   rule. */
.lct-tw svg:not([width]):not([height]) {
	width: 1em;
	height: 1em;
}

/* =========================================================================
   Layout — display, flex, grid
   ========================================================================= */

.lct-tw .tw-block         { display: block; }
.lct-tw .tw-inline        { display: inline; }
.lct-tw .tw-inline-block  { display: inline-block; }
.lct-tw .tw-inline-flex   { display: inline-flex; }
.lct-tw .tw-flex          { display: flex; }
.lct-tw .tw-grid          { display: grid; }
.lct-tw .tw-hidden        { display: none; }

/* The HTML5 `hidden` attribute must win over .tw-flex / .tw-grid /
   .tw-block / .tw-inline-* etc. The user-agent stylesheet applies
   `[hidden] { display: none }` at specificity (0,1,0), losing to any
   `.lct-tw .tw-flex` rule at (0,2,0). This rule restores the expected
   behavior so `previewNavWrap.hidden = true` (and every other
   `.hidden = true` toggle inside the plugin wrapper) actually hides
   the element. */
.lct-tw [hidden]          { display: none !important; }

/* Template description panel is a soft callout below the dropdown.
   When the active template carries no description (or the JS clears
   it during a savedDraft restore), the styled box would otherwise
   render as a blank pill. :empty collapses it so the gap closes
   cleanly until a description is set again. */
.lct-template-description:empty { display: none; }

.lct-tw .tw-flex-col      { flex-direction: column; }
.lct-tw .tw-flex-wrap     { flex-wrap: wrap; }
.lct-tw .tw-flex-1        { flex: 1 1 0; }

.lct-tw .tw-items-center  { align-items: center; }
.lct-tw .tw-items-start   { align-items: flex-start; }
.lct-tw .tw-justify-center  { justify-content: center; }
.lct-tw .tw-justify-between { justify-content: space-between; }

.lct-tw .tw-grid-cols-1   { grid-template-columns: 1fr; }
.lct-tw .tw-grid-cols-2   { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.lct-tw .tw-grid-cols-builder { grid-template-columns: 1fr; }

@media (min-width: 768px) {
	.lct-tw .md\:tw-grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.lct-tw .md\:tw-grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.lct-tw .md\:tw-grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.lct-tw .md\:tw-grid-cols-\[3fr_1fr\] { grid-template-columns: 3fr 1fr; }
	.lct-tw .md\:tw-col-span-2  { grid-column: span 2 / span 2; }
}

@media (min-width: 1024px) {
	.lct-tw .lg\:tw-grid-cols-builder { grid-template-columns: minmax(0, 1fr) 400px; }
	.lct-tw .lg\:tw-grid-cols-2       { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.lct-tw .lg\:tw-grid-cols-3       { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.lct-tw .lg\:tw-grid-cols-4       { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.lct-tw .lg\:tw-col-span-2        { grid-column: span 2 / span 2; }
	.lct-tw .lg\:tw-sticky            { position: sticky; }
	.lct-tw .lg\:tw-top-8             { top: 2rem; }
	.lct-tw .lg\:tw-self-start        { align-self: start; }
}

.lct-tw .tw-relative      { position: relative; }
.lct-tw .tw-absolute      { position: absolute; }
.lct-tw .tw-sticky        { position: sticky; }
.lct-tw .tw-top-2         { top: 0.5rem; }
.lct-tw .tw-right-2       { right: 0.5rem; }
.lct-tw .tw-top-8         { top: 2rem; }
.lct-tw .tw-z-2           { z-index: 2; }
.lct-tw .tw-z-10          { z-index: 10; }

/* =========================================================================
   Spacing — gap, padding, margin
   ========================================================================= */

.lct-tw .tw-gap-1         { gap: 0.25rem; }
.lct-tw .tw-gap-2         { gap: 0.5rem; }
.lct-tw .tw-gap-3         { gap: 0.75rem; }
.lct-tw .tw-gap-4         { gap: 1rem; }
.lct-tw .tw-gap-5         { gap: 1.25rem; }
.lct-tw .tw-gap-6         { gap: 1.5rem; }
.lct-tw .tw-gap-8         { gap: 2rem; }

.lct-tw .tw-p-1           { padding: 0.25rem; }
.lct-tw .tw-p-2           { padding: 0.5rem; }
.lct-tw .tw-p-3           { padding: 0.75rem; }
.lct-tw .tw-p-4           { padding: 1rem; }
.lct-tw .tw-p-5           { padding: 1.25rem; }
.lct-tw .tw-p-6           { padding: 1.5rem; }

.lct-tw .tw-px-2          { padding-left: 0.5rem;  padding-right: 0.5rem; }
.lct-tw .tw-px-3          { padding-left: 0.75rem; padding-right: 0.75rem; }
.lct-tw .tw-px-4          { padding-left: 1rem;    padding-right: 1rem; }
.lct-tw .tw-py-0\.5       { padding-top: 0.125rem; padding-bottom: 0.125rem; }
.lct-tw .tw-py-1          { padding-top: 0.25rem;  padding-bottom: 0.25rem; }
.lct-tw .tw-py-2          { padding-top: 0.5rem;   padding-bottom: 0.5rem; }
.lct-tw .tw-py-3          { padding-top: 0.75rem;  padding-bottom: 0.75rem; }
.lct-tw .tw-pt-2          { padding-top: 0.5rem; }
.lct-tw .tw-pt-3          { padding-top: 0.75rem; }
.lct-tw .tw-pt-4          { padding-top: 1rem; }

.lct-tw .tw-m-0           { margin: 0; }
.lct-tw .tw-mx-auto       { margin-left: auto; margin-right: auto; }
.lct-tw .tw-mt-1          { margin-top: 0.25rem; }
.lct-tw .tw-mt-2          { margin-top: 0.5rem; }
.lct-tw .tw-mt-4          { margin-top: 1rem; }
.lct-tw .tw-mb-1          { margin-bottom: 0.25rem; }
.lct-tw .tw-mb-2          { margin-bottom: 0.5rem; }

/* =========================================================================
   Sizing — width / height / max-width / min-height
   ========================================================================= */

.lct-tw .tw-w-full        { width: 100%; }
.lct-tw .tw-w-4           { width: 1rem; }
.lct-tw .tw-w-5           { width: 1.25rem; }
.lct-tw .tw-h-4           { height: 1rem; }
.lct-tw .tw-h-5           { height: 1.25rem; }

.lct-tw .tw-max-w-sm      { max-width: 24rem; }
.lct-tw .tw-max-w-full    { max-width: 100%; }

.lct-tw .tw-min-h-editor  { min-height: 16rem; }

/* Reset grid/flex children's default min-width so wide content (CodeMirror
   gutters, signature preview tables) doesn't push the track wider than its
   1fr allocation. Without this, the 1fr workspace column grows to fit its
   intrinsic content and squeezes the fixed 400px inspector track. */
.lct-tw .tw-min-w-0       { min-width: 0; }

/* =========================================================================
   Borders, radius, shadow
   ========================================================================= */

.lct-tw .tw-border        { border-width: 1px; border-style: solid; border-color: #e5e7eb; }
.lct-tw .tw-border-0      { border-width: 0; }
.lct-tw .tw-border-t      { border-top-width: 1px; border-top-style: solid; border-top-color: #e5e7eb; }
.lct-tw .tw-border-l      { border-left-width: 1px; border-left-style: solid; border-left-color: #e5e7eb; }
.lct-tw .tw-border-gray-200 { border-color: #e5e7eb; }
.lct-tw .tw-border-gray-300 { border-color: #d1d5db; }
.lct-tw .tw-border-green-200 { border-color: #bbf7d0; }
.lct-tw .tw-border-red-200   { border-color: #fecaca; }
.lct-tw .tw-border-amber-200 { border-color: #fde68a; }

.lct-tw .tw-rounded        { border-radius: 0.25rem; }
.lct-tw .tw-rounded-md     { border-radius: 0.375rem; }
.lct-tw .tw-rounded-lg     { border-radius: 0.5rem; }
.lct-tw .tw-rounded-xl     { border-radius: 0.75rem; }
.lct-tw .tw-rounded-2xl    { border-radius: 1rem; }
.lct-tw .tw-rounded-full   { border-radius: 9999px; }

.lct-tw .tw-shadow-sm     { box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); }
.lct-tw .tw-shadow        { box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1); }
.lct-tw .tw-shadow-md     { box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1); }
.lct-tw .tw-shadow-lg     { box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1); }
.lct-tw .tw-shadow-xl     { box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1); }

/* Ring utilities. Implemented via outline so they compose with the
   existing tw-shadow-* box-shadow utilities. tw-ring-1 sets the width
   (1px outline, offset inward by -1px so it doesn't add visual size),
   tw-ring-gray-200 supplies the color. */
.lct-tw .tw-ring-1            { outline: 1px solid; outline-offset: -1px; }
.lct-tw .tw-ring-gray-200     { outline-color: #e5e7eb; }

.lct-tw .tw-overflow-hidden { overflow: hidden; }
.lct-tw .tw-overflow-auto   { overflow: auto; }

/* =========================================================================
   Background colors
   ========================================================================= */

.lct-tw .tw-bg-white      { background-color: #ffffff; }
.lct-tw .tw-bg-gray-50    { background-color: #f9fafb; }
.lct-tw .tw-bg-gray-100   { background-color: #f3f4f6; }
.lct-tw .tw-bg-gray-200   { background-color: #e5e7eb; }
.lct-tw .tw-bg-gray-700   { background-color: #374151; }
.lct-tw .tw-bg-gray-900   { background-color: #111827; }
.lct-tw .tw-bg-blue-50    { background-color: #eff6ff; }
.lct-tw .tw-bg-blue-600   { background-color: #2563eb; }
.lct-tw .tw-bg-blue-700   { background-color: #1d4ed8; }
.lct-tw .tw-bg-green-50   { background-color: #f0fdf4; }
.lct-tw .tw-bg-red-50     { background-color: #fef2f2; }
.lct-tw .tw-bg-amber-50   { background-color: #fffbeb; }
.lct-tw .tw-bg-transparent { background-color: transparent; }

/* =========================================================================
   Text — size, weight, color, alignment
   ========================================================================= */

.lct-tw .tw-text-xs       { font-size: 0.75rem;  line-height: 1rem; }
.lct-tw .tw-text-sm       { font-size: 0.875rem; line-height: 1.25rem; }
.lct-tw .tw-text-base     { font-size: 1rem;     line-height: 1.5rem; }
.lct-tw .tw-text-lg       { font-size: 1.125rem; line-height: 1.75rem; }
.lct-tw .tw-text-xl       { font-size: 1.25rem;  line-height: 1.75rem; }
.lct-tw .tw-text-2xl      { font-size: 1.5rem;   line-height: 2rem; }

.lct-tw .tw-font-normal   { font-weight: 400; }
.lct-tw .tw-font-medium   { font-weight: 500; }
.lct-tw .tw-font-semibold { font-weight: 600; }
.lct-tw .tw-font-bold     { font-weight: 700; }

.lct-tw .tw-italic        { font-style: italic; }
.lct-tw .tw-not-italic    { font-style: normal; }

.lct-tw .tw-text-white       { color: #ffffff; }
.lct-tw .tw-text-gray-100    { color: #f3f4f6; }
.lct-tw .tw-text-gray-500    { color: #6b7280; }
.lct-tw .tw-text-gray-600    { color: #4b5563; }
.lct-tw .tw-text-gray-700    { color: #374151; }
.lct-tw .tw-text-gray-900    { color: #111827; }
.lct-tw .tw-text-blue-600    { color: #2563eb; }
.lct-tw .tw-text-green-700   { color: #15803d; }
.lct-tw .tw-text-green-800   { color: #166534; }
.lct-tw .tw-text-red-700     { color: #b91c1c; }
.lct-tw .tw-text-red-800     { color: #991b1b; }
.lct-tw .tw-text-amber-700   { color: #b45309; }
.lct-tw .tw-text-amber-800   { color: #92400e; }

.lct-tw .tw-text-center   { text-align: center; }
.lct-tw .tw-text-left     { text-align: left; }

.lct-tw .tw-uppercase     { text-transform: uppercase; }
.lct-tw .tw-tracking-wide { letter-spacing: 0.025em; }

.lct-tw .tw-leading-snug  { line-height: 1.375; }

/* =========================================================================
   Module h3 headings — override Breakdance theme defaults
   ========================================================================= */

.lct-shortcode-tool h3,
.lct-hc-content h3,
.lct-qr-root h3,
.lct-utm-wrapper h3 {
	margin: 0;
	font-size: 1.15rem;
	font-weight: 400;
	color: inherit;
}

/* =========================================================================
   Primary action button — global style for all modules
   ========================================================================= */

.lct-primary-action {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0.75rem 1.5rem;
	font-size: 1rem;
	font-weight: 600;
	color: #ffffff;
	background: linear-gradient(to bottom, #2563eb, #1d4ed8);
	border: none;
	border-radius: 0.375rem;
	cursor: pointer;
	transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease, opacity 0.15s ease;
	gap: 6px;
}

.lct-primary-action:hover:not(:disabled) {
	background: linear-gradient(to bottom, #1d4ed8, #1e40af);
	transform: translateY(-1px);
	box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.12), 0 2px 4px -2px rgba(0, 0, 0, 0.08);
}

.lct-primary-action:active:not(:disabled) {
	transform: translateY(0);
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

.lct-primary-action:disabled,
.lct-primary-action[disabled] {
	opacity: 0.6;
	cursor: not-allowed;
	transform: none;
	background: #2563eb;
}

/* =========================================================================
   Inputs / focus / hover / disabled / transitions
   ========================================================================= */

.lct-tw .tw-cursor-pointer    { cursor: pointer; }
.lct-tw .tw-cursor-not-allowed { cursor: not-allowed; }

.lct-tw .tw-outline-none      { outline: 2px solid transparent; outline-offset: 2px; }

.lct-tw .focus\:tw-outline-none:focus { outline: 2px solid transparent; outline-offset: 2px; }
.lct-tw .focus\:tw-ring-2:focus       { box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5); }
.lct-tw .focus\:tw-ring-blue-500:focus { box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5); }

.lct-tw .hover\:tw-bg-blue-700:hover  { background-color: #1d4ed8; }
.lct-tw .hover\:tw-bg-gray-50:hover   { background-color: #f9fafb; }
.lct-tw .hover\:tw-bg-gray-100:hover  { background-color: #f3f4f6; }
.lct-tw .hover\:tw-bg-gray-200:hover  { background-color: #e5e7eb; }
.lct-tw .hover\:tw-text-blue-700:hover { color: #1d4ed8; }

.lct-tw .disabled\:tw-opacity-60[disabled],
.lct-tw .disabled\:tw-opacity-60:disabled { opacity: 0.6; }
.lct-tw .disabled\:tw-cursor-not-allowed[disabled],
.lct-tw .disabled\:tw-cursor-not-allowed:disabled { cursor: not-allowed; }

.lct-tw .tw-transition { transition-property: color, background-color, border-color, opacity, transform, box-shadow; transition-duration: .15s; transition-timing-function: ease; }

/* =========================================================================
   Builder-specific named pieces preserved from old CSS
   ========================================================================= */

.lct-signature-preview {
	display: block;
	transition: background .25s ease, color .25s ease;
}

.lct-preview-cell {
	padding: 0;
	background: transparent;
}

.lct-signatures-table {
	width: 100%;
	border-collapse: collapse;
}

.lct-signatures-table > thead > tr > th,
.lct-signatures-table > tbody > tr > td {
	padding: 12px;
	text-align: start;
	vertical-align: top;
	border-bottom: 1px solid #e5e7eb;
	font-size: 13px;
}

.lct-signatures-table > tbody > tr {
	position: relative;
}

/* Vertical icon stack for the per-row Copy / Download actions. Positioned
   by the JS-injected .lct-row-actions wrapper (tw-absolute tw-top-2
   tw-right-2 tw-z-10), so neither button takes positioning of its own. */
.lct-row-actions {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
}

/* (removed) .lct-row-copy { position: absolute; top: 2rem; right: 2rem; }
   The legacy absolute positioning fought the flex stack above. The button
   now flows inside .lct-row-actions and inherits its position from the
   wrapper. */

.lct-preview-frame {
	border-radius: 18px;
	padding: 1rem;
	overflow: hidden;
	/* Height + opacity transitions drive the smooth fade + resize
	   animation when the preview content swaps. JS pins an explicit
	   height before the swap and releases after the transition; CSS
	   handles the easing curve and timing. */
	transition: opacity .2s ease, height .25s ease, background .25s ease, color .25s ease, box-shadow .25s ease;
}

/* Substituted variable values inside Template Preview render at 80%
   opacity so authors can visually distinguish row data from static
   authored template text. Scoped to .lct-preview-frame so identical
   markup in the bulk results table / downloaded HTML is unaffected.

   Also style variables inside attribute values — when a variable appears
   inside href/src/etc., it's NOT wrapped in a span (to avoid breaking
   markup), so we highlight via a data-attribute rule on the parent. */
.lct-preview-frame .lct-preview-variable {
	opacity: 0.7;
	background-color: rgba(59, 130, 246, 0.1);
	border: 1px dashed rgba(59, 130, 246, 0.4);
	padding: 2px 4px;
	border-radius: 3px;
}

/* Highlight variables inside attributes by wrapping the entire attribute
   in a visible context. For attributes like href="{{Website}}", we can't
   inject a span without breaking markup, so we use a CSS-only approach:
   mark the parent element that contains the variable. This is a fallback
   for variables in attribute context. */
.lct-preview-body a[href*="{{"],
.lct-preview-body img[src*="{{"],
.lct-preview-body img[alt*="{{"] {
	outline: 1px dashed rgba(59, 130, 246, 0.3);
	outline-offset: -1px;
}

.lct-preview-body {
  max-width: 100%;
  overflow-x: hidden;
}

.lct-preview-body * {
  max-width: 100% !important;
}

.lct-preview-body img {
  height: auto !important;
}
/* Animate divider thickness changes in the preview. Targets common
   border-* declarations on table cells inside the signature preview so a
   live tweak to {{DividerThickness}} eases visually instead of snapping.
   Scoped to .lct-signature-preview so it never bleeds into UI chrome. */
.lct-signature-preview td,
.lct-signature-preview tr,
.lct-signature-preview table {
	transition: border-top-width .25s ease, border-bottom-width .25s ease, border-color .25s ease;
}

/* Preview update fade. Lowering opacity further than .4 produces a
   visible blink; .35 keeps the silhouette visible during the swap so
   the height transition has something to ease against. The nav
   heading dims in sync via .is-updating toggled by JS — they live in
   sibling containers so a CSS-only sync is not possible. */
.lct-preview-frame.is-updating { opacity: .35; }
.lct-preview-nav             { transition: opacity .2s ease; }
.lct-preview-nav.is-updating { opacity: .4; }
.lct-preview-nav-prev,
.lct-preview-nav-next {
	cursor: pointer;
	line-height: 1;
	font-size: 1.1rem;
	min-width: 2rem;
}
.lct-preview-nav-prev:disabled,
.lct-preview-nav-next:disabled { cursor: not-allowed; }

.lct-preview-frame.lct-theme-dark { background: #111827; color: #e5e7eb; }
.lct-preview-frame.lct-theme-light { background: #ffffff; color: #111827; }

.lct-preview-placeholder { color: #9ca3af; font-style: italic; }

.lct-pill {
	display: inline-flex;
	align-items: center;
	padding: 0.25rem 0.5rem;
	border-radius: 9999px;
	font-size: 0.75rem;
	font-weight: 500;
	background: #f3f4f6;
	color: #374151;
}
.lct-pill-matched { background: #dcfce7; color: #166534; }
.lct-pill-missing { background: #fee2e2; color: #991b1b; }
.lct-pill-unused  { background: #fef3c7; color: #92400e; }
.lct-pill-neutral { background: #f3f4f6; color: #374151; }
.lct-pill-system  { background: #e5e7eb; color: #4b5563; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

/* SaaS-style hover tooltip used to describe each system variable token
   shown under an accordion field label.

   Z-INDEX / OVERFLOW STRATEGY
   ---------------------------
   The trigger is positioned `relative` so the ::after pseudo anchors
   to it. The pseudo uses z-index:100 to win over sibling stacking
   contexts (segmented controls, pills, etc.). But absolute children
   are still clipped by the nearest `overflow:hidden` ancestor — and
   the accordion content wrapper (.lct-tw details > div) needs
   `overflow:hidden` for its grid-template-rows open/close animation
   to clip during transitions.

   The fix lives in the accordion block below: once an accordion is
   FULLY OPEN, that wrapper's overflow swaps to `visible` via a
   transition-delay equal to the open animation's duration. Closed
   and mid-animation states keep the wrapper clipped so we don't
   reveal half-rendered content. Tooltips inside an open accordion
   render unclipped; tooltips in a closing accordion are simply
   torn down with the rest of the content. */
/* .lct-token-tip lives in assets/css/ui-components.css (lifted to the
   plugin-wide stylesheet so every module can reuse it). The esig builder
   inherits it via the LCT_Assets::HANDLE_UI_COMPONENTS dependency
   declared in processor.php's wp_register_style call. */

.lct-pill[draggable="true"]        { cursor: grab; }
.lct-pill[draggable="true"]:active { cursor: grabbing; }
.lct-pulse-once                    { animation: lctPulseOnce .6s ease-out; }

@keyframes lctPulseOnce {
	0%   { transform: scale(1);    box-shadow: 0 0 0 0 rgba(59, 130, 246, .35); }
	50%  { transform: scale(1.05); box-shadow: 0 0 0 6px rgba(59, 130, 246, 0); }
	100% { transform: scale(1);    box-shadow: 0 0 0 0 rgba(59, 130, 246, 0); }
}

.lct-generate-animate { animation: lctGenerateEnable .28s ease-out; }

@keyframes lctGenerateEnable {
	0%   { transform: translateY(2px);  opacity: .85; }
	60%  { transform: translateY(-1px); opacity: 1; }
	100% { transform: translateY(0); }
}

.lct-variables-check {
	font-size: .9rem;
	color: #16a34a;
	opacity: 0;
	transform: translateY(2px);
	transition: opacity .18s ease, transform .18s ease;
}
.lct-variables-check.is-visible { opacity: 1; transform: translateY(0); }

.lct-disabled-reason {
	margin: 8px 0 0;
	font-size: .8rem;
	color: #b91c1c;
	min-height: 1.1em;
	text-align: center;
}
.lct-disabled-reason:empty { display: none; }

.lct-dropzone {
	border: 2px dashed #d1d5db;
	border-radius: 0.5rem;
	padding: 1.5rem;
	text-align: center;
	cursor: pointer;
	transition: background-color .15s ease, border-color .15s ease;
}
.lct-dropzone:hover,
.lct-dropzone.is-dragover { background-color: #f0f9ff; border-color: #2563eb; }
.lct-dropzone.is-valid    { border-color: #16a34a; background-color: #f0fdf4; }
.lct-dropzone.is-invalid  { border-color: #dc2626; background-color: #fef2f2; }

.lct-status-line {
	padding: 4px 8px;
	font-size: .85rem;
	border-left: 3px solid transparent;
	margin-top: 4px;
}
.lct-status-line.lct-status-danger  { color: #991b1b; background: #fef2f2; border-left-color: #dc2626; }
.lct-status-line.lct-status-warning { color: #92400e; background: #fef3c7; border-left-color: #f59e0b; }
.lct-status-line.lct-status-info    { color: #075985; background: #f0f9ff; border-left-color: #0ea5e9; }
.lct-status-line.lct-status-neutral { color: #4b5563; background: #f9fafb; border-left-color: #d1d5db; }

/* CAPTCHA wrap — center the Turnstile widget under the Generate button.
   The provider emits <div class="lct-captcha-wrap tw-py-3"><div class="cf-turnstile"…/></div>;
   the inner widget is fixed-width (~300px) and would otherwise sit
   flush-left inside the Generate card. text-align:center on the wrap
   centers the inline-block widget across the available width. */
.lct-captcha-wrap {
	text-align: center;
}

/* =========================================================================
   Template picker — visual card grid
   =========================================================================
   2 / 3-column grid of cards, each holding a (visually hidden but
   keyboard-focusable) radio input and a procedurally-rendered SVG
   thumbnail. Thumbnail interiors use a fixed light-grey palette
   (slate-200 panels + slate-300 accent shapes) — they're structural
   previews, not chromatic ones, so they read the same regardless of
   the user's session brand color.

   Brand color stays where identity belongs: the SELECTED card's
   border + checkmark badge (driven by the --lct-thumb-brand CSS
   variable on the grid container; syncThumbBrand in
   signature-builder.js updates it from state.advanced.brandColor
   whenever the user's brand color changes). */

.lct-tw .lct-template-grid {
	/* Reset fieldset default styling. */
	border: 0;
	padding: 12px;
	margin: 0;
	min-width: 0;
	/* Grid layout — 2 columns up to 1023px, 3 columns at >= 1024px. */
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 16px;
	/* Limit visible templates to ~9 per screen with vertical scrolling. */
	max-height: 520px;
	overflow-y: auto;
	overflow-x: hidden;
	/* Reserve space for scrollbar without it overlapping content. */
	scrollbar-gutter: stable;
}
@media (min-width: 1024px) {
	.lct-tw .lct-template-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/* Visually-hidden screen-reader label (used for the fieldset legend). */
.lct-tw .lct-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* Each card wraps a thumbnail + label + checkmark badge. Hover lifts
   the card slightly and tints the border in brand color; selected
   adds a brand-color ring + reveals the checkmark badge. */
.lct-tw .lct-template-card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: 6px 6px 8px;
	background: #ffffff;
	border: 1px solid #e5e7eb;
	border-radius: 8px;
	cursor: pointer;
	transition:
		border-color .15s ease,
		box-shadow .15s ease,
		transform .15s ease,
		background-color .15s ease;
}
.lct-tw .lct-template-card:hover {
	border-color: var(--lct-thumb-brand, #2563eb);
	box-shadow: 0 4px 12px -6px rgba(15, 23, 42, .15);
	transform: translateY(-1px);
}
.lct-tw .lct-template-card.is-selected {
	border-color: var(--lct-thumb-brand, #2563eb);
	box-shadow: 0 0 0 1px var(--lct-thumb-brand, #2563eb), 0 4px 12px -6px rgba(15, 23, 42, .18);
	background: #f8fafc;
}

/* Radio input is visually hidden but stays in the focus order — labels
   wrap it so click / tap / arrow keys all reach it. A subtle focus ring
   on the card itself signals the focused state for keyboard users. */
.lct-tw .lct-template-card-input {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}
.lct-tw .lct-template-card:focus-within {
	outline: 2px solid var(--lct-thumb-brand, #2563eb);
	outline-offset: 2px;
}

/* Thumbnail container — a tinted slate background so the slate-gray
   placeholder rects (logo, photo, identity, row) read as content
   shapes against a non-white surface. Aspect-ratio 6/5 matches the
   renderer's 120×100 viewBox; pre-reserved height prevents grid jank
   during initial paint. */
.lct-tw .lct-template-card-thumb {
	display: block;
	background: #f8fafc;
	border-radius: 5px;
	overflow: hidden;
	aspect-ratio: 6 / 5;
	padding: 0;
}
/* The thumbnail SVG ships with `width` and `height` attributes so
   the global FOUC backstop (.lct-tw svg:not([width]):not([height]))
   doesn't clamp it to 1em × 1em. The CSS rules below override the
   attribute defaults at render time so the SVG fills the panel. */
.lct-tw .lct-template-card-thumb .lct-thumb-svg {
	display: block;
	width: 100%;
	height: 100%;
}

.lct-tw .lct-template-card-label {
	font-size: 11.5px;
	font-weight: 500;
	color: #374151;
	text-align: center;
	line-height: 1.3;
	/* Single-line truncation — long template names don't blow up the
	   card height when there's no room. Tooltip is the full name. */
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.lct-tw .lct-template-card.is-selected .lct-template-card-label {
	color: #111827;
	font-weight: 600;
}

/* Checkmark badge in the top-right corner. Hidden by default, revealed
   when the card is selected. Filled circle with white checkmark. */
.lct-tw .lct-template-card-check {
	position: absolute;
	top: 6px;
	right: 6px;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background: var(--lct-thumb-brand, #2563eb);
	color: #ffffff;
	display: flex;
	align-items: center;
	justify-content: center;
	opacity: 0;
	transform: scale(0.85);
	transition: opacity .15s ease, transform .15s ease;
	pointer-events: none;
}
.lct-tw .lct-template-card.is-selected .lct-template-card-check {
	opacity: 1;
	transform: scale(1);
}

/* Custom Template card — same skeleton, but the thumbnail panel is
   tinted differently so it reads as the "build your own" outlier. */
.lct-tw .lct-template-card-custom .lct-template-card-thumb {
	background: #f9fafb;
	border: 1px dashed #cbd5e1;
}

/* Reduced-motion users opt out of hover lift + transitions. */
@media (prefers-reduced-motion: reduce) {
	.lct-tw .lct-template-card,
	.lct-tw .lct-template-card-check {
		transition: none;
	}
	.lct-tw .lct-template-card:hover {
		transform: none;
	}
}

/* Template-config conflict banner. Renders inside .lct-section-templates
   under the dropdown when a user-initiated template switch would change
   settings the user has already tuned. Two-button choice:
   [Apply this template's settings] / [Keep mine]. Self-dismisses on
   either click or on the next template switch. */
.lct-template-config-banner {
	margin-top: 0.75rem;
	padding: 10px 12px;
	background: #eff6ff;
	border: 1px solid #93c5fd;
	border-radius: 8px;
	font-size: 12.5px;
	color: #1e3a8a;
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.lct-template-config-banner-msg { line-height: 1.4; }
.lct-template-config-banner-actions { display: flex; gap: 8px; }
.lct-template-config-banner-apply,
.lct-template-config-banner-keep {
	border: 1px solid #d1d5db;
	background: #ffffff;
	color: #1f2937;
	padding: 4px 10px;
	border-radius: 6px;
	font-size: 12.5px;
	font-weight: 500;
	cursor: pointer;
	transition: background-color .12s ease, border-color .12s ease;
}
.lct-template-config-banner-apply {
	background: #2563eb;
	border-color: #1d4ed8;
	color: #ffffff;
}
.lct-template-config-banner-apply:hover { background: #1d4ed8; }
.lct-template-config-banner-keep:hover  { background: #f8fafc; }

/* Template-card secondary action buttons. Two buttons sit side-by-side
   under the template description: "Load a saved signature" (restores a
   prior export) and "Download a sample CSV" (downloads a CSV pre-filled
   with the current template's column headers). Soft-outlined visual so
   they read as equal-weight options without competing with the template
   select above them. Wraps to two stacked rows on narrow screens. */
.lct-template-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-top: 0.5rem;
}
.lct-template-action {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 10px;
	background: transparent;
	border: 1px solid #d1d5db;
	border-radius: 6px;
	color: #374151;
	font-size: 12px;
	font-weight: 500;
	cursor: pointer;
	transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.lct-template-action:hover,
.lct-template-action:focus-visible {
	background: #f8fafc;
	border-color: #94a3b8;
	color: #1e3a8a;
}
.lct-template-action:focus-visible {
	outline: 2px solid #93c5fd;
	outline-offset: 2px;
}
.lct-template-action svg {
	color: #94a3b8;
	flex-shrink: 0;
	transition: color .12s ease;
}
.lct-template-action:hover svg,
.lct-template-action:focus-visible svg {
	color: #2563eb;
}

/* =========================================================================
   Advanced accordion category grouping
   ========================================================================= */

.lct-adv-group {
	padding-top: 14px;
	margin-top: 14px;
	border-top: 1px solid rgba(0, 0, 0, .08);
}
.lct-adv-group:first-child { padding-top: 0; margin-top: 0; border-top: 0; }
.lct-adv-group-title {
	margin: 0 0 10px;
	font-size: .75rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: #6b7280;
}

/* =========================================================================
   CodeMirror validator integration (CSS only — JS sets markers on cm)
   ========================================================================= */

.CodeMirror-gutter.lct-validation-gutter { width: 18px; }

.lct-validator-gutter {
	display: inline-block;
	width: 14px;
	text-align: center;
	font-weight: 700;
	cursor: help;
	user-select: none;
}
.lct-validator-gutter--error   { color: #dc2626; }
.lct-validator-gutter--warning { color: #d97706; }

.lct-validator-mark             { border-radius: 2px; cursor: help; }
.lct-validator-mark--error      { background: rgba(220, 38, 38, .14); border-bottom: 2px solid #dc2626; }
.lct-validator-mark--warning    { background: rgba(217, 119, 6, .14); border-bottom: 2px dotted #d97706; }

/* =========================================================================
   Theme-toggle (sun/moon SVGs)
   ========================================================================= */

.lct-theme-toggle-wrap {
	position: relative;
	display: inline-block;
	width: 1.2em;
	height: 1.2em;
	flex-shrink: 0;
}
.lct-theme-toggle {
	position: absolute;
	top: 0;
	left: 0;
	cursor: pointer;
	transition: opacity .2s ease;
	opacity: 0;
	pointer-events: none;
	font-size: 1.1em;
	line-height: 1;
}
.lct-theme-toggle.is-visible { opacity: 1; pointer-events: auto; }
.lct-theme-toggle svg        { width: 1.1em; height: 1.1em; display: block; }

/* Icon-button sizing — preview download span and per-row copy/download
   buttons match the theme-toggle icon footprint (1.1em square, currentColor
   inherited). Keeps the inspector affordances visually consistent. */
.lct-preview-download         { cursor: pointer; color: #4b5563; display: inline-flex; }
.lct-preview-download:hover   { color: #111827; }
.lct-preview-download svg,
.lct-row-copy svg,
.lct-row-download svg         { width: 1.1em; height: 1.1em; display: block; }

/* =========================================================================
   Micro-interaction polish
   ========================================================================= */

/* Accordion chevron — rotates 180° when its parent <details> is open.
   Injected at runtime by signature-builder.js into every <summary> that
   doesn't already contain one. */
.lct-accordion-chevron {
	display: inline-block;
	width: 14px;
	height: 14px;
	flex-shrink: 0;
	transition: transform .2s ease;
}
details[open] > summary .lct-accordion-chevron {
	transform: rotate(180deg);
}

/* Preview refresh — replaces the prior pure-opacity fade with a subtle
   scale-down. Cubic-bezier easing avoids the linear/ease pop that came
   off as cheap. */
.lct-preview-frame {
	transition: opacity .18s ease, transform .18s cubic-bezier(.4,0,.2,1), background .25s ease, color .25s ease, box-shadow .25s ease;
}
.lct-preview-frame.is-updating {
	opacity: .5;
	transform: scale(.98);
}

/* Primary action lift. Translate + softer shadow on hover; reset both
   when the button is disabled so we never look interactive while gated. */
.lct-submit {
	transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease, opacity .15s ease;
}
.lct-submit:not(:disabled) {
	background: linear-gradient(to bottom, #2563eb, #1d4ed8);
}
.lct-submit:not(:disabled):hover {
	transform: translateY(-1px);
	box-shadow: 0 4px 6px -1px rgba(0, 0, 0, .12), 0 2px 4px -2px rgba(0, 0, 0, .08);
}
.lct-submit:disabled,
.lct-submit[disabled] {
	transform: none;
	background: #2563eb;
}

/* Secondary button hover shadow. Targets the named secondary buttons
   we render natively. The selector list is explicit so we don't catch
   accidental UI chrome. */
.lct-row-copy,
.lct-row-download,
.lct-mode-btn,
.lct-preview-mode-btn {
	transition: transform .12s ease, box-shadow .12s ease, background-color .12s ease, color .12s ease;
}
.lct-row-copy:hover,
.lct-row-download:hover,
.lct-mode-btn:hover,
.lct-preview-mode-btn:hover {
	box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}

/* Pill hover lift. Pills are dragged; the lift hints draggability. */
.lct-pill {
	transition: transform .12s ease, box-shadow .12s ease, background-color .12s ease;
}
.lct-pill:hover {
	transform: translateY(-1px);
	box-shadow: 0 2px 4px rgba(0, 0, 0, .08);
}

/* ==========================================
   Generated signature row hover highlight
   ========================================== */

.lct-signatures-table > tbody > tr {
	transition: background-color 180ms ease, box-shadow 180ms ease;
}

.lct-signatures-table > tbody > tr:hover {
	background-color: #fffdf5; /* subtle brand-adjacent warmth */
}

/* Subtle inset polish for preview cell only */
.lct-signatures-table > tbody > tr:hover .lct-preview-cell {
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.03);
}

/* ==========================================
   Item 3 — admin/shortcode page wrapper layout
   ========================================== */

.lct-tw.lct-wrap {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}


/* ==========================================
   Item 6 — variables panel spacing
   ========================================== */

.lct-tw .lct-section-variables .lct-variables-pills {
	gap: 0.5rem;
}
/* Status line only gets vertical breathing room when it actually has
   content. The status element is always present in the DOM (JS toggles
   its text), so without :not(:empty) the margin leaves dead space
   under the pills whenever the template has no problems to report. */
.lct-tw .lct-section-variables .lct-variables-status:not(:empty) {
	margin-top: 0.75rem;
}

/* ==========================================
   Item 8 — signature preview overflow constraint
   ========================================== */

.lct-signature-preview img,
.lct-signature-preview table {
	max-width: 100%;
}
.lct-signature-preview {
	overflow-x: auto;
	overflow-wrap: anywhere;
	word-break: break-word;
}

/* ==========================================
   Smooth accordion open/close (SaaS polish)
   ==========================================

   `grid-template-rows: 0fr → 1fr` is the cross-browser way to animate
   `auto` height without JS measurement. Works in Chrome 117+, Firefox
   113+, Safari 16+. Browsers without support gracefully fall back to
   the native instant toggle.

   Pattern: the immediate child of <details> after <summary> is the
   content wrapper (a <div>). We slot that into a CSS grid whose row
   track interpolates between 0fr (closed) and 1fr (open).

   POLISH (SaaS feel):
   - cubic-bezier(.4, 0, .2, 1) — Material/Linear-style "standard" easing.
     The default `ease` curve is symmetric; this curve front-loads the
     movement and decelerates, which reads as "intentional" rather than
     "elastic."
   - Opacity fade overlaid on the height interpolation — content emerges
     instead of suddenly appearing at full intensity.
   - Slight transform micro-lift on close — the content settles upward by
     2px as it collapses, hinting at the dismiss direction.

   OVERFLOW STRATEGY (tooltip fix):
   - Closed / animating-closed: `overflow: hidden` on the wrapper clips
     the half-rendered content during the row-track interpolation.
   - Fully open: `overflow: visible` so absolutely-positioned tooltips
     (.lct-token-tip::after) can render above the wrapper.
   - The switch is scheduled by `transition: overflow 0s .3s` ONLY in the
     open state. `overflow` is non-animatable, but with `transition-delay`
     it changes discretely at the end of the open animation. On close,
     the open-state rule no longer applies, so overflow reverts to
     `hidden` instantly — content is clipped throughout the close. */
.lct-tw details > div {
	display: grid;
	grid-template-rows: 0fr;
	overflow: hidden;
	opacity: 0;
	transform: translateY(-2px);
	transition:
		grid-template-rows .3s cubic-bezier(.4, 0, .2, 1),
		opacity .22s ease-out,
		transform .3s cubic-bezier(.4, 0, .2, 1);
}
.lct-tw details[open] > div {
	grid-template-rows: 1fr;
	opacity: 1;
	transform: translateY(0);
	overflow: visible;
	transition:
		grid-template-rows .3s cubic-bezier(.4, 0, .2, 1),
		opacity .22s ease-out,
		transform .3s cubic-bezier(.4, 0, .2, 1),
		overflow 0s .3s;
}
.lct-tw details > div > * {
	min-height: 0;
}

/* ==========================================
   Item 4 — Generate button state animation
   (reusable: any .lct-btn-state can opt in via the same classes)
   ========================================== */

/* Spinner glyph — works as either child of a button or standalone */
.lct-spinner {
	display: inline-block;
	width: 1em;
	height: 1em;
	border: 2px solid currentColor;
	border-right-color: transparent;
	border-radius: 50%;
	animation: lctSpin .8s linear infinite;
	vertical-align: -2px;
}
@keyframes lctSpin {
	to { transform: rotate(360deg); }
}

/* Inline icon glyphs used by the submit state machine */
.lct-icon-check,
.lct-icon-x {
	display: inline-block;
	font-weight: 700;
	line-height: 1;
}

/* Submit button states — visual flash, not layout shift.
   .is-busy:   spinner shown; pointer disabled via [disabled] attr.
   .is-success: green background + check icon, holds for ~1s.
   .is-error:   red background + x icon, holds for ~1s. */
.lct-submit {
	transition: transform .15s ease, box-shadow .15s ease, background-color .25s ease, opacity .15s ease;
}
.lct-submit.is-busy {
	background: #2563eb;
	cursor: progress;
}
.lct-submit.is-success {
	background: #16a34a !important;
	background-image: none !important;
	transform: none;
	box-shadow: 0 0 0 3px rgba(22, 163, 74, .25);
}
.lct-submit.is-error {
	background: #dc2626 !important;
	background-image: none !important;
	transform: none;
	box-shadow: 0 0 0 3px rgba(220, 38, 38, .25);
}

/* Screen-reader-only label for icon-only button states. Bridges the
   gap when the visible content is replaced by a spinner / icon. */
.lct-tw .tw-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* =========================================================================
   SaaS ELEVATION LAYER (Linear / Stripe / Notion treatment)

   This block is intentionally last in the file so its rules win on equal
   specificity vs. the utility classes above. It does NOT remove any
   tw-* utilities from the markup — it overrides the visual outcome on
   the named .lct-* hooks the markup already carries.

   Design intent: structured, intentional, calm. No bright gradients,
   no heavy animations. Borders are nearly invisible; depth comes from
   restrained shadows. Typography hierarchy is tightened.
   ========================================================================= */

/* ---------- Workspace shell ---------- */

/* The builder root used to read as "boxed". Drop the grey wash to an
   even softer tone and pad more generously so cards float in air rather
   than being packed into a tray. */
.lct-tw .lct-builder {
	background-color: #f8fafc;
	padding: 2rem;
	border-radius: 14px;
	gap: 2rem;
}
@media (max-width: 767px) {
	.lct-tw .lct-builder { padding: 1.25rem; gap: 1.5rem; }
}

/* ---------- Product header (canonical shared style) ----------
   Single source of truth for the top-of-surface header used by EVERY
   module. Linear / Vercel feel: tight letter-spacing, near-black
   headline, muted-slate subhead, modest bottom margin.

   The rule targets BOTH h1 and h2 so modules embedded inside an admin
   page (which already owns the h1) can use h2 for their headline
   without losing the canonical typography. Use only one heading per
   header — the rule applies the same look to either.

   Modules should:
     <header class="lct-product-header">
       <h2>Tool name</h2>          (or h1, if at top-level)
       <p>One-line subhead.</p>
       <p class="lct-product-header-docs"><a href="…">How to use this tool ↗</a></p>
     </header>
*/
.lct-tw .lct-product-header {
	margin-bottom: 1.25rem;
}

/* Email Signature Generator header — mode toggle left, tour actions right */
.lct-tw .lct-esig-header {
	display: flex !important;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: nowrap;
}

.lct-tw .lct-esig-header .lct-mode-toggle {
	flex-shrink: 0;
}

.lct-tw .lct-esig-header .lct-tour-header-actions {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-shrink: 0;
	white-space: nowrap;
}

.lct-tw .lct-product-header p {
	color: #64748b;
	font-size: 0.9375rem;
	margin: 0;
}
/* No top margin: the docs link now sits inside the flex
   .lct-tour-header-actions row next to the "Take a tour" button, where a
   top margin would break vertical centering. Spacing below the header is
   owned by the row's own margin-top. */
.lct-tw .lct-product-header .lct-product-header-docs a {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
	font-size: .85rem;
	color: #2563eb;
	text-decoration: none;
	font-weight: 500;
}
.lct-tw .lct-product-header .lct-product-header-docs a:hover {
	text-decoration: underline;
}

/* ---------- Section card elevation ---------- */

/* Cards previously read as "boxed" with a hard 1px border and tiny
   shadow. SaaS admin UIs (Linear, Notion, Stripe) elevate cards using
   a near-invisible border + restrained shadow + slightly larger radius.
   The card now feels lifted off the canvas rather than drawn on it. */
.lct-tw .lct-card {
	background-color: #ffffff;
	border-radius: 12px;
	border: 1px solid rgba(15, 23, 42, .06);
	box-shadow:
		0 1px 2px rgba(15, 23, 42, .04),
		0 1px 0 rgba(15, 23, 42, .02);
	transition: box-shadow .2s ease, border-color .2s ease;
}

/* Cards that contain an open accordion get a subtle additional lift so
   the active section stands out from collapsed siblings. :has() is
   widely supported (Chrome 105+, Safari 15.4+, Firefox 121+); browsers
   without :has() simply skip the lift, which is acceptable. */
.lct-tw .lct-card.lct-section-advanced:has(> details[open]) {
	box-shadow:
		0 4px 12px -4px rgba(15, 23, 42, .08),
		0 1px 2px rgba(15, 23, 42, .04);
	border-color: rgba(15, 23, 42, .09);
}

/* Workspace / inspector card padding lift. The HTML still carries
   tw-p-5; our override increases it without touching markup. */
.lct-tw .lct-card.lct-section-templates,
.lct-tw .lct-card.lct-section-editor,
.lct-tw .lct-card.lct-section-variables,
.lct-tw .lct-card.lct-section-data,
.lct-tw .lct-card.lct-section-single,
.lct-tw .lct-card.lct-section-advanced,
.lct-tw .lct-card.lct-section-preview {
	padding: 1.25rem;
}
@media (min-width: 1024px) {
	.lct-tw .lct-card.lct-section-preview {
		padding: 1.5rem;
	}
}

/* Section headlines inside cards get tighter, more confident typography. */
.lct-tw .lct-card .lct-card-header h2,
.lct-tw .lct-card .lct-card-header h3 {
	color: #0f172a;
	letter-spacing: -0.005em;
	margin: 0;
}
.lct-tw .lct-card .lct-card-header h2 {
	font-size: 1.0625rem;
	font-weight: 600;
}
.lct-tw .lct-card .lct-card-header h3 {
	font-size: 0.875rem;
	font-weight: 600;
}

/* "Must fill" indicator next to Your Information — amber dot that only
   appears in Single mode. The builder root carries data-gen-mode="single"
   or "bulk"; CSS uses that attribute to flip visibility. */
.lct-tw .lct-must-fill {
	display: none;
	color: #f59e0b;
	font-size: .9em;
	line-height: 1;
	flex-shrink: 0;
}
.lct-tw .lct-builder-app[data-gen-mode="single"] .lct-must-fill {
	display: inline-block;
}

/* ---------- Accordion summary (Linear settings feel) ---------- */

/* Remove the default disclosure marker cross-browser. The chevron is
   already injected by signature-builder.js as .lct-accordion-chevron;
   showing both produces visual duplication. */
.lct-tw details > summary {
	list-style: none;
}
.lct-tw details > summary::-webkit-details-marker {
	display: none;
}
.lct-tw details > summary::marker {
	display: none;
	content: "";
}

/* Larger click target, subtle hover state, calm color. The HTML's
   tw-px-2 tw-py-2 is overridden by this more-specific selector. */
.lct-tw .lct-section-advanced > details > summary {
	padding: 14px 16px;
	border-radius: 12px;
	color: #0f172a;
	font-weight: 600;
	cursor: pointer;
	transition: background-color .15s ease, color .15s ease;
	-webkit-tap-highlight-color: transparent;
	user-select: none;
}
.lct-tw .lct-section-advanced > details > summary:hover {
	background-color: #f8fafc;
}
.lct-tw .lct-section-advanced > details > summary:focus-visible {
	outline: 2px solid #3b82f6;
	outline-offset: 2px;
}
.lct-tw .lct-section-advanced > details[open] > summary {
	border-radius: 12px 12px 0 0;
	border-bottom: 1px solid rgba(15, 23, 42, .06);
}

/* Chevron rests at a calmer grey; the existing rotation rule above
   handles the open-state flip. */
.lct-tw .lct-accordion-chevron { color: #94a3b8; }

/* ---------- Segmented controls (mode / preview-mode) ---------- */

/* The HTML uses a flex row with `tw-overflow-hidden` and JS class-swaps
   `tw-bg-blue-600 tw-text-white` ↔ `tw-bg-white tw-text-gray-700` to
   mark active state. That reads as "two buttons in a box" — not as a
   segmented control. Override the container to a tray-with-pill pattern:
   the tray has a soft grey background; the active button is a raised
   white pill that floats over the tray. JS continues to drive selection
   via the existing class swap. */
.lct-tw .lct-mode-toggle,
.lct-tw .lct-preview-mode-toggle {
	padding: 3px;
	gap: 2px;
	background-color: #f1f5f9;
	border: 1px solid rgba(15, 23, 42, .06);
	border-radius: 8px;
}

/* All buttons in either segmented control share the inactive look.
   Higher specificity than the .tw-bg-* utilities so transparent wins
   when JS sets tw-bg-white on the inactive button. */
.lct-tw .lct-mode-toggle .lct-mode-btn,
.lct-tw .lct-preview-mode-toggle .lct-preview-mode-btn {
	flex: 1;
	border: 0;
	border-radius: 6px;
	background-color: transparent;
	color: #475569;
	font-weight: 500;
	cursor: pointer;
	text-wrap: nowrap;
	white-space: nowrap;
	transition: background-color .15s ease, color .15s ease, box-shadow .15s ease;
}
.lct-tw .lct-mode-toggle .lct-mode-btn:hover,
.lct-tw .lct-preview-mode-toggle .lct-preview-mode-btn:hover {
	color: #0f172a;
}

/* Active pill — the variant JS marks with tw-bg-blue-600. Higher
   specificity than the utility classes so the override wins without
   !important. */
.lct-tw .lct-mode-toggle .lct-mode-btn.tw-bg-blue-600,
.lct-tw .lct-preview-mode-toggle .lct-preview-mode-btn.tw-bg-blue-600 {
	background-color: #ffffff;
	color: #0f172a;
	box-shadow:
		0 1px 2px rgba(15, 23, 42, .08),
		0 1px 0 rgba(15, 23, 42, .03);
}

/* The active button's white text class becomes meaningless once we
   force dark color above — but keep the rule resilient if a future JS
   variant uses a different background color. */
.lct-tw .lct-mode-toggle .lct-mode-btn.tw-text-white,
.lct-tw .lct-preview-mode-toggle .lct-preview-mode-btn.tw-text-white {
	color: #0f172a;
}

/* ---------- Primary submit button polish ---------- */

/* Softer gradient + tighter focus ring. The earlier rule (above in this
   file) provides the lift-on-hover and the .is-busy/.is-success/.is-error
   states. This block only refines the resting/focus appearance so the
   overall feel is calm and confident rather than loud. */
.lct-tw .lct-submit {
	border: 0;
	border-radius: 8px;
	font-weight: 600;
	letter-spacing: 0.005em;
}
.lct-tw .lct-submit:focus-visible {
	outline: none;
	box-shadow:
		0 0 0 3px rgba(37, 99, 235, .22),
		0 4px 8px -2px rgba(15, 23, 42, .12);
}

/* ---------- Variables / template-vars section ---------- */

/* The "Template Variables" sub-header that lists draggable system
   tokens reads better with a touch more breathing room than the
   detected-variables panel above it. */
.lct-tw .lct-template-vars-divider {
	border-top-color: rgba(15, 23, 42, .06);
}

/* ---------- Editor pane comfort ---------- */

/* The CodeMirror textarea fallback default is small. Bump line-height
   so multi-line templates are easier to scan. CodeMirror's own font
   metrics are handled by its theme. */
.lct-tw .lct-cm-textarea {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 13px;
	line-height: 1.6;
}

/* CodeMirror editor itself — ensure consistent font sizing */
.lct-tw .CodeMirror {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace !important;
	font-size: 13px !important;
	line-height: 1.6 !important;
}

.lct-tw .CodeMirror-lines {
	padding: 4px 0;
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 13px;
}

/* ---------- Mode-toggle row spacing ---------- */

/* Vertical rhythm in the inspector: the mode-toggle and tertiary action
   row felt cramped against the submit button. A tiny lift via gap+margin
   gives each row its own band. */
.lct-tw .lct-mode-toggle-row {
	margin-top: 0.25rem;
}
.lct-tw .lct-tertiary-actions {
	margin-top: 0.5rem;
}

/* ---------- Lint panel (preview warnings) ---------- */

/* The lint panel under the preview is a <details> too, but it should
   NOT participate in the advanced-accordion exclusivity behavior
   (handled by data-accordion-group). Its visual treatment is also
   different — a quiet outlined card, not an elevated section. */
.lct-tw .lct-lint-panel {
	border: 1px solid rgba(15, 23, 42, .08);
	border-radius: 8px;
	background-color: #fdfdfd;
}
.lct-tw .lct-lint-panel > summary {
	padding: 10px 12px;
	border-radius: 8px;
}
.lct-tw .lct-lint-panel[open] > summary {
	border-bottom: 1px solid rgba(15, 23, 42, .06);
	border-radius: 8px 8px 0 0;
}

/* =========================================================================
   Form-field primitives (consistent label / token / input rhythm)

   These named classes replace the previous ad-hoc combinations of
   utilities. The HTML still carries the tw-flex / tw-flex-col / tw-gap-*
   utilities; the named .lct-field rule below tightens vertical rhythm to
   match Stripe/Linear form spacing. The override only kicks in when an
   ancestor carries .lct-field, so legacy tw-* combos elsewhere are
   untouched.
   ========================================================================= */

/* Field stack — label / token-tip / control. The 6px gaps are a deliberate
   compromise: tight enough to read as one logical field, breathing enough
   that the dotted-or-clean monospace token doesn't crowd the label. */
.lct-tw .lct-field {
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-width: 0;
}
.lct-tw .lct-field-label {
	font-size: 0.75rem;
	font-weight: 500;
	color: #475569;
	line-height: 1.2;
}
.lct-tw .lct-field-token {
	font-size: 0.6875rem;
	color: #94a3b8;
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	align-self: flex-start;
	line-height: 1.2;
}
/* When the token is hover-aware, restore .lct-token-tip's positioning
   semantics so the popover still anchors to it. Cursor is pointer (not
   help) because click-to-copy is the primary affordance now — the
   tooltip still appears on hover/focus, but the click action takes
   precedence in the cursor signal. */
.lct-tw .lct-field-token.lct-token-tip {
	position: relative;
	cursor: pointer;
}

/* ---------- CTA missing-field warning ----------
   Inline amber notice that appears below the Button Size dropdown in
   the Footer panel when the user has picked a size (small/medium/large)
   but hasn't filled in Text and/or URL — without both, the renderer
   suppresses the button so this warning is the user-facing explanation
   for "why doesn't my button appear?". Hidden by default via the
   `hidden` attribute; JS syncCtaWarning() toggles visibility on every
   state change. Sits side-by-side with the existing field-alert styling
   (same amber palette as .lct-field-alert) so the language reads
   consistently across the panel. */
.lct-tw .lct-cta-warning {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 8px 10px;
	background: #fffbeb;
	border: 1px solid #fde68a;
	border-radius: 6px;
	color: #92400e;
	font-size: 11.5px;
	line-height: 1.4;
}
.lct-tw .lct-cta-warning[hidden] {
	display: none;
}
.lct-tw .lct-cta-warning svg {
	flex-shrink: 0;
	color: #d97706;
}
.lct-tw .lct-cta-warning-msg {
	flex: 1 1 auto;
}

/* ---------- Unused-variable indicator ----------
   Configuration fields whose umbrella token doesn't appear in the
   currently selected template get an amber warning glyph inline with
   the token, and every input/textarea/select inside the field is
   disabled (via the JS toggling the `disabled` attribute). The label,
   token, and inputs all dim so the field reads as "this control
   doesn't do anything right now" without removing it entirely — the
   field returns to full opacity the moment the user picks a template
   that uses the variable. */
.lct-tw .lct-field-alert {
	display: none;
	align-items: center;
	vertical-align: middle;
	color: #d97706;
	line-height: 0;
	cursor: help;
	flex-shrink: 0;
}
/* `.has-alert` is the explicit "show the warning icon" toggle —
   separated from `.is-unused` (which only handles the disabled
   appearance). Lets CTA fields disable silently when the user picks
   "No CTA Button" while still showing the amber icon for fields whose
   underlying variable is truly absent from the template. */
.lct-tw .lct-field.has-alert .lct-field-alert {
	display: inline-flex;
}
/* Token + alert share one row inside .lct-field. justify-content:
   space-between keeps the token flush-left and the alert flush-right;
   when the alert is hidden (no .has-alert on parent), the row
   collapses visually to just the token. */
.lct-tw .lct-field-token-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	min-width: 0;
}
.lct-tw .lct-field-token-row .lct-field-token {
	/* Cancel the standalone `align-self: flex-start` from the column
	   layout context — inside this row, the token's vertical position
	   is governed by the row's align-items: center. */
	align-self: center;
	min-width: 0;
}
.lct-tw .lct-field.is-unused .lct-field-label,
.lct-tw .lct-field.is-unused .lct-field-token {
	opacity: 0.55;
}
.lct-tw .lct-field.is-unused input,
.lct-tw .lct-field.is-unused textarea,
.lct-tw .lct-field.is-unused select {
	background: #f8fafc;
	color: #94a3b8;
	cursor: not-allowed;
}
/* Reduce contrast on disabled color-pickers — the native swatch
   button keeps a strong fill otherwise, which fights the "I'm
   disabled" signal we set on the rest of the field. */
.lct-tw .lct-field.is-unused input[type="color"] {
	opacity: 0.5;
	filter: grayscale(0.6);
}

/* Color input — square swatch (40×40) rather than the prior 64×40 rectangle.
   The form name and class hooks remain untouched; only the visual box
   changes via the named .lct-color-swatch override the markup adopts. */
.lct-tw .lct-color-swatch {
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid #d1d5db;
	border-radius: 8px;
	cursor: pointer;
	background-color: transparent;
}
.lct-tw .lct-color-swatch::-webkit-color-swatch-wrapper { padding: 0; }
.lct-tw .lct-color-swatch::-webkit-color-swatch { border: none; border-radius: 6px; }
.lct-tw .lct-color-swatch::-moz-color-swatch { border: none; border-radius: 6px; }

/* Joined swatch + hex text input.

   The native <input type="color"> always stores its value as #rrggbb,
   but the browser's picker UI opens in RGB / HSL mode by default on
   macOS / Safari. HTML provides no attribute to override that. The
   SaaS-conventional fix (Stripe / Linear / Notion / Vercel) is to lift
   a hex text field to be the primary input modality, with the swatch
   as a secondary affordance that still opens the native picker for
   users who prefer a visual chooser.

   The two inputs are bi-directionally synced by JS:
   bindColorHexSync() — typing a valid hex updates the swatch, choosing
   from the swatch updates the hex. Read paths (readBrandingFromUI)
   still go through the swatch's .value, so the existing storage
   semantics are unchanged. */
.lct-tw .lct-color-input-group {
	display: inline-flex;
	align-items: stretch;
	border-radius: 8px;
	overflow: hidden;
	background-color: #ffffff;
	transition: border-color .15s ease, box-shadow .15s ease;
}
.lct-tw .lct-color-input-group .lct-color-swatch {
	border: 0;
	border-radius: 0;
	width: 40px;
	height: 40px;
	flex-shrink: 0;
	cursor: pointer;
}
.lct-tw .lct-color-input-group .lct-color-hex {
	border: 0;
	border-left: 1px solid #e2e8f0;
	padding: 0 10px;
	width: 92px;
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 13px;
	color: #1f2937;
	background-color: transparent;
	text-transform: uppercase;
	outline: none;
}
.lct-tw .lct-color-input-group .lct-color-hex:focus {
	outline: none;
}
.lct-tw .lct-color-input-group .lct-color-hex.is-invalid {
	color: #b91c1c;
}

/* =========================================================================
   Input group with trailing suffix (Stripe-style joined unit)

   Pattern:  [ input ] [ suffix ]  rendered as a single visual control.
   The input and suffix share a continuous border; the suffix has a
   neutral background so the unit reads as a label, not as data.

   Markup:
   <div class="lct-input-group">
     <input class="lct-input-group-control ...existing input utilities..." />
     <span class="lct-input-group-suffix">px</span>
   </div>

   This replaces the previous absolute-positioned suffix pattern
   (<div class="tw-relative"><input ... tw-pr-8><span tw-absolute>px</span></div>),
   which crowded the value against the unit. Source order means our
   .lct-input-group-control rules win on equal specificity over the
   tw-rounded-md / tw-border utilities that the input still carries.
   ========================================================================= */
.lct-tw .lct-input-group {
	display: flex;
	align-items: stretch;
	width: 100%;
	min-width: 0;
}
.lct-tw .lct-input-group .lct-input-group-control {
	flex: 1 1 0;
	min-width: 0;
	border-top-right-radius: 0;
	border-bottom-right-radius: 0;
	border-right-width: 0;
	border-right-style: solid;
}
.lct-tw .lct-input-group .lct-input-group-suffix {
	display: inline-flex;
	align-items: center;
	padding: 0 10px;
	background-color: #f8fafc;
	border: 1px solid #d1d5db;
	border-left: 1px solid #e2e8f0;
	border-top-right-radius: 6px;
	border-bottom-right-radius: 6px;
	color: #64748b;
	font-size: 12px;
	font-weight: 500;
	white-space: nowrap;
	user-select: none;
}
/* Focus highlight on the joint — when the input is focused, the suffix
   border picks up the same blue tint so the assembly reads as one
   control rather than two. */
.lct-tw .lct-input-group:focus-within .lct-input-group-suffix {
	border-color: #93c5fd;
	background-color: #eff6ff;
	color: #1d4ed8;
}

/* =========================================================================
   Customize HTML section polish
   ========================================================================= */

/* The "Advanced" pill on the Customize HTML summary. Subtle slate-blue,
   uppercase micro-type, soft border. Telegraphs "you are entering an
   advanced area" without dominating the heading. Matches the visual
   language of the Admin-only docs pill (amber over fef3c7) but uses a
   cooler palette so the two badges aren't confused. */
.lct-tw .lct-advanced-badge {
	display: inline-flex;
	align-items: center;
	font-size: 9.5px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	background: #eef2ff;
	color: #4338ca;
	border: 1px solid #c7d2fe;
	padding: 2px 7px;
	border-radius: 9999px;
	line-height: 1.4;
	white-space: nowrap;
	vertical-align: middle;
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
/* When the accordion opens, soften the badge so the heading visually
   becomes the primary handle for "I am here". The transition makes the
   shift feel intentional, not a redraw. */
.lct-tw .lct-section-advanced > details[open] > summary .lct-advanced-badge {
	background: #f1f5f9;
	color: #64748b;
	border-color: #e2e8f0;
}

/* Sophisticated content reveal: when an Advanced accordion opens, its
   inner content panel fades up by a few pixels with an ease-out so the
   transition feels considered rather than mechanical. Native <details>
   can't animate its own height in evergreen browsers without
   `interpolate-size: allow-keywords` (Chrome 129+ only) — animating the
   *content* instead gets us 90% of the perceived motion with zero
   compatibility risk. The fade is short enough to feel native, not
   spinny. Applies to every Advanced accordion uniformly so the
   Customize HTML one doesn't feel out of place. */
@keyframes lctAccordionContentReveal {
	from {
		opacity: 0;
		transform: translateY(-4px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}
.lct-tw .lct-section-advanced > details[open] > div,
.lct-tw .lct-section-advanced > details[open] > .tw-p-6 {
	animation: lctAccordionContentReveal .22s cubic-bezier(.22, .61, .36, 1) both;
}

/* Reduced-motion accessibility — skip the reveal animation for users who
   prefer reduced motion. The accordion still opens; it just opens
   instantly without the translate/fade. */
@media (prefers-reduced-motion: reduce) {
	.lct-tw .lct-section-advanced > details[open] > div,
	.lct-tw .lct-section-advanced > details[open] > .tw-p-6 {
		animation: none;
	}
	.lct-tw .lct-accordion-chevron {
		transition: none;
	}
}

/* Lean Variables card — keep the pills + status visually quiet so they
   read as informational, not a call-to-action. The card itself uses the
   standard shadow-sm; this rule only refines the inner spacing for the
   tighter layout. */
.lct-tw .lct-section-variables .lct-variables-pills:empty {
	display: none;
}
.lct-tw .lct-section-variables .lct-variables-status:empty {
	margin-top: 0;
}

/* When the Customize HTML accordion is collapsed, its descendants are
   display:none anyway, but Safari sometimes paints a 1px residual
   border. Belt-and-suspenders: force the contents to opacity 0 when
   closed so any browser quirk renders invisibly. */
.lct-tw .lct-adv-group-html > details:not([open]) > div {
	opacity: 0;
}

/* =========================================================================
   v1.2.0 — Visual hierarchy & color system
   ========================================================================= */

/* Workspace background — soft warm-cool gradient. Subtle enough that
   most users won't consciously notice; just enough that the eye doesn't
   slide off the all-white surface. Replaces the flat tw-bg-gray-50. */
.lct-tw .lct-builder {
	background: linear-gradient(170deg, #f8fafc 0%, #eef2f7 60%, #f1f5f9 100%);
}

/* Per-category accent stripes on the left edge of each Advanced
   accordion card. Stripe is 3px wide, slate by default, intensifying
   to a category-specific hue when the accordion is open. Hidden on the
   non-advanced top cards (Templates, Variables, Your Info, CSV) so the
   visual signal is scoped to the optional/advanced surface. */
.lct-tw .lct-section-advanced {
	position: relative;
	overflow: hidden;
}
.lct-tw .lct-section-advanced::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 3px;
	background: #cbd5e1;
	transition: background-color .25s ease;
	z-index: 1;
	pointer-events: none;
}
.lct-tw .lct-section-advanced:has(> details[open])::before {
	background: var(--lct-accent, #4f46e5);
}
.lct-tw .lct-section-advanced.lct-adv-group-single { --lct-accent: #2563eb; }      /* blue   */
.lct-tw .lct-section-advanced.lct-adv-group-visuals { --lct-accent: #7c3aed; }     /* violet */
.lct-tw .lct-section-advanced.lct-adv-group-type-layout { --lct-accent: #0891b2; } /* cyan   */
.lct-tw .lct-section-advanced.lct-adv-group-footer { --lct-accent: #b45309; }      /* amber  */
.lct-tw .lct-section-advanced.lct-adv-group-html { --lct-accent: #4338ca; }        /* indigo */

/* Active-accordion ring — when an Advanced accordion is open, the
   card itself picks up a 2px tinted ring (replacing the flat 1px
   border) so the active surface reads decisively. Subtle box-shadow
   adds a soft lift. */
.lct-tw .lct-card.lct-section-advanced:has(> details[open]) {
	border-color: rgba(15, 23, 42, .08);
	box-shadow: 0 2px 4px rgba(15, 23, 42, .04), 0 0 0 1px var(--lct-accent, #4f46e5);
}

/* Accordion summary icon — slate at rest, category hue when open. */
.lct-tw .lct-acc-icon,
.lct-tw .lct-card-icon {
	color: #94a3b8;
	flex-shrink: 0;
	transition: color .2s ease;
}
.lct-tw .lct-section-advanced > details[open] > summary .lct-acc-icon {
	color: var(--lct-accent, #4f46e5);
}

/* Section-title icons on always-visible cards (Templates, Variables,
   CSV upload). Match the accordion icon color treatment at rest;
   no open-state because these aren't accordions. */
.lct-tw .lct-section-templates .lct-card-icon,
.lct-tw .lct-section-variables .lct-card-icon,
.lct-tw .lct-section-data .lct-card-icon {
	color: #64748b;
}

/* ---------- Mode toggle (now prominent at top of workspace) ---------- */

/* Pill the active button so the toggle reads as a segmented control,
   not "two buttons in a tray." */
.lct-tw .lct-mode-toggle-prominent {
	padding-bottom: 4px;
}
.lct-tw .lct-mode-toggle-prominent .lct-mode-toggle {
	padding: 4px;
	gap: 3px;
	background: #f1f5f9;
	border-radius: 10px;
	border-color: rgba(15, 23, 42, .08);
	box-shadow: inset 0 1px 2px rgba(15, 23, 42, .04);
}
.lct-tw .lct-mode-toggle-prominent .lct-mode-btn {
	border-radius: 7px;
	transition: background-color .2s ease, color .2s ease, box-shadow .2s ease;
}
.lct-tw .lct-mode-toggle-prominent .lct-mode-btn.tw-bg-blue-600 {
	background: #ffffff !important;
	color: #1e3a8a !important;
	box-shadow: 0 1px 3px rgba(15, 23, 42, .08), 0 0 0 1px rgba(37, 99, 235, .15);
}
.lct-tw .lct-mode-toggle-prominent .lct-mode-btn.tw-bg-white {
	background: transparent !important;
	color: #64748b !important;
	box-shadow: none;
	text-wrap: nowrap;
}
.lct-tw .lct-mode-toggle-prominent .lct-mode-btn:hover {
	background: rgba(255, 255, 255, .55) !important;
}
.lct-tw .lct-mode-toggle-prominent .lct-mode-btn.tw-bg-blue-600:hover {
	background: #ffffff !important;
}

/* ---------- Dropzone refinement ---------- */

.lct-tw .lct-dropzone {
	padding: 28px 20px;
	transition: border-color .18s ease, background-color .18s ease, transform .18s ease;
}
.lct-tw .lct-dropzone:hover,
.lct-tw .lct-dropzone:focus-within {
	transform: translateY(-1px);
}
.lct-dropzone-icon {
	display: flex;
	justify-content: center;
	color: #94a3b8;
	transition: color .2s ease, transform .2s ease;
}
.lct-tw .lct-dropzone:hover .lct-dropzone-icon,
.lct-tw .lct-dropzone:focus-within .lct-dropzone-icon {
	color: #2563eb;
	transform: scale(1.06);
}
.lct-tw .lct-dropzone.is-dragover .lct-dropzone-icon {
	color: #2563eb;
}

/* ---------- Tertiary action buttons (Sample CSV / Reset) ---------- */

.lct-tw .lct-tertiary-btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 12px;
	font-size: 12px;
	font-weight: 500;
	color: #475569;
	background: #ffffff;
	border: 1px solid #e2e8f0;
	border-radius: 7px;
	cursor: pointer;
	transition: color .15s ease, background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.lct-tw .lct-tertiary-btn:hover {
	color: #1e3a8a;
	background: #f8fafc;
	border-color: #cbd5e1;
	box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
}
.lct-tw .lct-tertiary-btn:focus-visible {
	outline: 2px solid #3b82f6;
	outline-offset: 2px;
}
.lct-tw .lct-tertiary-btn svg {
	color: #94a3b8;
	transition: color .15s ease;
}
.lct-tw .lct-tertiary-btn:hover svg {
	color: #2563eb;
}

/* Reset gets a warning-tinted hover so the destructive action reads
   distinctly from the informational Sample CSV button. */
.lct-tw .lct-tertiary-btn.lct-reset-btn:hover {
	color: #b45309;
	background: #fefce8;
	border-color: #fde68a;
}
.lct-tw .lct-tertiary-btn.lct-reset-btn:hover svg {
	color: #b45309;
}

/* Disabled-reason callout styling moved to the persistent bottom bar
   (.lct-bottom-bar-submit .lct-disabled-reason) — see the bottom-bar
   block below. The amber-card treatment no longer fits a single-row
   horizontal layout; the reason is now plain amber text aligned to
   the right of Generate. */

/* ---------- Submit button glow when enabled ---------- */

.lct-tw .lct-submit {
	box-shadow: 0 1px 2px rgba(37, 99, 235, .12);
	transition: background-color .2s ease, box-shadow .25s ease, transform .15s ease;
}
.lct-tw .lct-submit:hover:not(:disabled) {
	box-shadow: 0 6px 16px -4px rgba(37, 99, 235, .35), 0 2px 4px rgba(37, 99, 235, .15);
	transform: translateY(-1px);
}
.lct-tw .lct-submit:active:not(:disabled) {
	transform: translateY(0);
	box-shadow: 0 1px 2px rgba(37, 99, 235, .2);
}
.lct-tw .lct-submit:disabled {
	box-shadow: none;
}

/* ---------- Preview frame label ---------- */

/* Subtle device-frame treatment for the preview area. A small dotted
   "preview" indicator in the top-left reinforces "this is what your
   recipient sees" without changing the rendered surface inside. The
   preview area itself stays white (or slate-900 in dark) so it
   simulates email clients accurately. */
.lct-tw .lct-section-preview {
	position: relative;
}
.lct-tw .lct-section-preview .lct-preview-frame {
	box-shadow: inset 0 0 0 1px rgba(15, 23, 42, .04);
	border-radius: 8px;
}

/* ---------- KPI strip (admin page) ----------
   Standalone CSS — does not depend on Tailwind utilities, because the
   admin page renders the strip OUTSIDE the .lct-tw scope on some hosts
   (the wrapping .lct-tw exists but utility classes like tw-px-5, tw-py-4,
   tw-divide-x, tw-mt-0.5 aren't in the hand-curated tailwind-builder.css
   subset and would silently no-op). All padding, dividers, typography,
   and responsive stacking are declared here. */
.lct-kpi-strip {
	display: flex;
	flex-direction: column;
	background: #ffffff;
	border: 1px solid #e5e7eb;
	border-radius: 8px;
	box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
	overflow: hidden;
	margin-bottom: 1.5rem;
}
.lct-kpi-strip .lct-kpi-cell {
	flex: 1 1 0;
	padding: 16px 20px;
	transition: background-color .15s ease;
	min-width: 0;
}
.lct-kpi-strip .lct-kpi-cell + .lct-kpi-cell {
	border-top: 1px solid #e5e7eb;
}
.lct-kpi-strip .lct-kpi-title {
	font-size: 10px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: #64748b;
	line-height: 1.4;
}
.lct-kpi-strip .lct-kpi-value {
	font-size: 1.625rem;
	font-weight: 700;
	color: #0f172a;
	line-height: 1.2;
	margin-top: 2px;
	font-variant-numeric: tabular-nums;
}
.lct-kpi-strip .lct-kpi-label {
	font-size: 12px;
	color: #6b7280;
	line-height: 1.4;
	margin-top: 2px;
}
.lct-kpi-strip .lct-kpi-cell:hover {
	background: #f8fafc;
}
@media (min-width: 768px) {
	.lct-kpi-strip {
		flex-direction: row;
	}
	.lct-kpi-strip .lct-kpi-cell + .lct-kpi-cell {
		border-top: 0;
		border-left: 1px solid #e5e7eb;
	}
}

/* ---------- Variables card pill polish ---------- */

/* Variables card gets a subtle slate-tinted background so it reads as
   informational rather than as another input surface. */
.lct-tw .lct-section-variables {
	background: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%);
}

/* ---------- Typography hierarchy on always-visible cards ---------- */

/* Templates and Variables get bigger headings than the data-input
   accordions so the primary scan-order is unmistakable. */
.lct-tw .lct-section-templates .lct-card-header h2,
.lct-tw .lct-section-data .lct-card-header h2 {
	font-size: 1.05rem;
	letter-spacing: -0.01em;
}

/* Reduced-motion accessibility — strip all the transitions added
   above for users who prefer reduced motion. */
@media (prefers-reduced-motion: reduce) {
	.lct-tw .lct-section-advanced::before,
	.lct-tw .lct-acc-icon,
	.lct-tw .lct-card-icon,
	.lct-tw .lct-mode-toggle-prominent .lct-mode-btn,
	.lct-tw .lct-dropzone,
	.lct-tw .lct-dropzone-icon,
	.lct-tw .lct-tertiary-btn,
	.lct-tw .lct-submit,
	.lct-kpi-strip .lct-kpi-cell {
		transition: none;
	}
	.lct-tw .lct-dropzone:hover,
	.lct-tw .lct-dropzone:focus-within,
	.lct-tw .lct-submit:hover:not(:disabled) {
		transform: none;
	}
}

/* =========================================================================
   v1.0.0 — 3-COLUMN LAYOUT
   ---------------------------------------------------------------------
   Top bar (mode toggle) sits above the grid. The .lct-builder-3col grid
   becomes the canvas:
     ≥ 1024px → three columns (nav 220 · workspace 1fr · inspector 380)
     ≥ 768px  → two columns   (nav 200 · workspace 1fr) — inspector hides
     < 768px  → single column — nav hides too, pager drives flow
   ========================================================================= */

.lct-tw .lct-builder-3col {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1.5rem;
	background: linear-gradient(170deg, #f8fafc 0%, #eef2f7 60%, #f1f5f9 100%);
	padding: 1.25rem;
	border-radius: 12px;
}
@media (min-width: 768px) {
	.lct-tw .lct-builder-3col {
		grid-template-columns: 200px minmax(0, 1fr);
	}
}
@media (min-width: 1024px) {
	.lct-tw .lct-builder-3col {
		grid-template-columns: 220px minmax(0, 1fr) 380px;
	}
}

/* ---------- Column 1: Section nav ---------- */

.lct-tw .lct-section-nav {
	display: flex;
	flex-direction: column;
	gap: 4px;
	position: sticky;
	top: 1rem;
	align-self: start;
	max-height: calc(100vh - 2rem);
	overflow-y: auto;
}
/* Section nav grouping */
.lct-tw .lct-section-nav-group {
	display: flex;
	flex-direction: column;
	gap: 4px;
	margin-bottom: 12px;
}

.lct-tw .lct-section-nav-group:last-child {
	margin-bottom: 0;
}

.lct-tw .lct-section-nav-group-title {
	padding: 0;
	margin: 0;
	font-size: 0.75rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: #6b7280;
	margin-bottom: 6px;
}

.lct-tw .lct-section-nav-group:first-child .lct-section-nav-group-title {
	margin-bottom: 6px;
}

.lct-tw .lct-section-nav-group-items {
	display: flex;
	flex-direction: column;
	gap: 0;
}

@media (max-width: 767px) {
	.lct-tw .lct-section-nav {
		position: relative;
		top: auto;
		max-height: none;
		flex-direction: column;
		gap: 8px;
		overflow: visible;
		padding: 0;
		background: transparent;
		border: none;
		border-radius: 0;
		margin-bottom: 1rem;
	}
	.lct-tw .lct-section-nav-group {
		flex-direction: column;
		gap: 4px;
		margin-bottom: 12px;
	}
	.lct-tw .lct-section-nav-group-title {
		display: block;
		font-size: 0.65rem;
		font-weight: 700;
		text-transform: uppercase;
		letter-spacing: 0.5px;
		color: #6b7280;
		margin: 0 0 6px 0;
		padding: 0;
	}
	.lct-tw .lct-section-nav-group-items {
		flex-direction: row;
		gap: 4px;
		flex-wrap: wrap;
	}
}
.lct-tw .lct-section-nav-btn {
	display: flex;
	align-items: center;
	gap: 10px;
	width: 100%;
	padding: 10px 12px;
	background: transparent;
	border: 1px solid transparent;
	border-radius: 8px;
	color: #475569;
	font-size: 13px;
	font-weight: 500;
	cursor: pointer;
	text-align: left;
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
@media (max-width: 767px) {
	.lct-tw .lct-section-nav-btn {
		width: auto;
		padding: 8px 10px;
		font-size: 12px;
		gap: 6px;
		flex-shrink: 0;
		white-space: nowrap;
	}
}
.lct-tw .lct-section-nav-btn:hover {
	background: rgba(255, 255, 255, 0.7);
	color: #0f172a;
}
.lct-tw .lct-section-nav-btn:focus-visible {
	outline: 2px solid #3b82f6;
	outline-offset: 2px;
}
.lct-tw .lct-section-nav-btn.is-active {
	background: #ffffff;
	border-color: rgba(15, 23, 42, .08);
	color: #1e3a8a;
	box-shadow: 0 1px 3px rgba(15, 23, 42, .06), 0 0 0 1px rgba(37, 99, 235, .12);
}
.lct-tw .lct-section-nav-icon {
	display: inline-flex;
	flex-shrink: 0;
	width: 18px;
	height: 18px;
	color: #94a3b8;
	transition: color .15s ease;
}
.lct-tw .lct-section-nav-btn.is-active .lct-section-nav-icon { color: #2563eb; }
.lct-tw .lct-section-nav-label {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.lct-tw .lct-section-nav-pip {
	display: inline-block;
	width: 6px;
	height: 6px;
	border-radius: 9999px;
	background: transparent;
	transition: background-color .15s ease;
}
.lct-tw .lct-section-nav-btn.has-progress .lct-section-nav-pip { background: #3b82f6; }
.lct-tw .lct-section-nav-btn.has-complete .lct-section-nav-pip { background: #10b981; }
.lct-tw .lct-section-nav-btn.has-warning  .lct-section-nav-pip { background: #f59e0b; }
.lct-tw .lct-section-nav-advanced .lct-advanced-badge {
	margin-left: auto;
	font-size: 9px;
}

/* ---------- Column 2: Workspace (section panels) ---------- */

.lct-tw .lct-workspace.lct-section-panels {
	min-width: 0;
}
.lct-tw .lct-section-panel {
	background: #ffffff;
	border: 1px solid #e5e7eb;
	border-radius: 12px;
	padding: 1.5rem;
	box-shadow: 0 1px 3px rgba(15, 23, 42, .04);
}
.lct-tw .lct-section-panel + .lct-section-panel {
	margin-top: 1rem;
}
.lct-tw .lct-panel-header {
	margin-bottom: 1.25rem;
}
.lct-tw .lct-panel-title {
	font-size: 1.25rem;
	font-weight: 700;
	color: #0f172a;
	margin: 0 0 4px 0;
	letter-spacing: -0.01em;
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}
.lct-tw .lct-panel-sub {
	font-size: 13px;
	color: #6b7280;
	margin: 0;
	line-height: 1.5;
}
.lct-tw .lct-panel-body {
	min-width: 0;
}
/* Default vertical rhythm for panel bodies. Panels that need a
   different gap (Brand & Visuals / Type & Layout / Footer use
   tw-gap-6; Customize HTML uses tw-gap-3) opt out via the
   tw-gap-* utility on the same element — the :not() guard
   keeps those overrides intact. */
.lct-tw .lct-panel-body:not([class*="tw-gap-"]) {
	display: flex;
	flex-direction: column;
	gap: 1rem;
}
.lct-tw .lct-subsection-title {
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: #64748b;
	margin-bottom: 8px;
	display: flex;
	align-items: baseline;
	gap: 8px;
	flex-wrap: wrap;
}
.lct-tw .lct-subsection-hint {
	font-size: 11px;
	font-weight: 400;
	text-transform: none;
	letter-spacing: normal;
	color: #94a3b8;
}
.lct-tw .lct-subsection-divider {
	border: 0;
	border-top: 1px solid #e5e7eb;
	margin: .25rem 0;
}

/* ---------- Column 3: Inspector ---------- */

.lct-tw .lct-inspector {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	min-width: 0;
}
@media (min-width: 1024px) {
	.lct-tw .lct-inspector {
		position: sticky;
		top: 1rem;
		align-self: start;
		/* No independent scrolling — inspector constrains to container height.
		   Preview window handles vertical overflow. */
	}
}
@media (max-width: 1023px) {
	/* Inspector is always visible on mobile — no toggle button needed. */
	.lct-tw .lct-inspector {
		display: flex;
	}
}

/* ---------- Mobile pager (under column 2 at < 768px) ---------- */

.lct-tw .lct-section-pager {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	margin-top: 1rem;
	padding: 8px 12px;
	background: #ffffff;
	border: 1px solid #e5e7eb;
	border-radius: 8px;
}
.lct-tw .lct-section-pager .lct-template-action {
	margin: 0;
}
.lct-tw .lct-section-pager-position {
	font-size: 12px;
	color: #64748b;
	font-variant-numeric: tabular-nums;
}
.lct-tw .lct-section-prev[disabled],
.lct-tw .lct-section-next[disabled] {
	opacity: .4;
	cursor: not-allowed;
}

/* ---------- Preview toggle button (tablet only) ---------- */

.lct-tw .lct-preview-toggle {
	display: none;
}

/* ---------- Color picker — hex-first layout (HubSpot pattern) ----------
   Markup: [hex text input] [native color input as swatch button]
   The hex input is the primary control; the swatch is a clickable
   square that triggers the native picker. Order: hex first (full-width
   primary), swatch second (fixed 40px square). */

.lct-tw .lct-color-input-group--hex-first {
	display: flex;
	gap: 6px;
	align-items: stretch;
}
.lct-tw .lct-color-input-group--hex-first .lct-color-hex {
	flex: 1;
	min-width: 0;
	padding: 8px 10px;
	font-size: 13px;
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	border: 1px solid #d1d5db;
	border-radius: 6px;
	background: #ffffff;
	color: #0f172a;
	transition: border-color .15s ease, box-shadow .15s ease;
}
.lct-tw .lct-color-input-group--hex-first .lct-color-hex:focus {
	outline: none;
	border-color: #3b82f6;
	box-shadow: 0 0 0 3px rgba(59, 130, 246, .15);
}
.lct-tw .lct-color-input-group--hex-first .lct-color-hex.is-invalid {
	border-color: #ef4444;
	box-shadow: 0 0 0 3px rgba(239, 68, 68, .12);
}
.lct-tw .lct-color-input-group--hex-first .lct-color-swatch {
	flex-shrink: 0;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid #d1d5db;
	border-radius: 6px;
	cursor: pointer;
	transition: border-color .15s ease, box-shadow .15s ease;
	-webkit-appearance: none;
	appearance: none;
	background: none;
}
.lct-tw .lct-color-input-group--hex-first .lct-color-swatch:hover {
	border-color: #94a3b8;
	box-shadow: 0 0 0 3px rgba(148, 163, 184, .15);
}
.lct-tw .lct-color-input-group--hex-first .lct-color-swatch::-webkit-color-swatch-wrapper { padding: 2px; }
.lct-tw .lct-color-input-group--hex-first .lct-color-swatch::-webkit-color-swatch         { border: 0; border-radius: 4px; }
.lct-tw .lct-color-input-group--hex-first .lct-color-swatch::-moz-color-swatch            { border: 0; border-radius: 4px; }

/* ---------- Mode-only visibility helpers ---------- */

.lct-tw[data-gen-mode="single"] .lct-mode-only-bulk { display: none; }
.lct-tw[data-gen-mode="bulk"]   .lct-mode-only-single { display: none; }
.lct-tw[data-gen-mode="single"] .lct-label-bulk { display: none; }
.lct-tw[data-gen-mode="bulk"]   .lct-label-single { display: none; }

/* ---------- Field labels ---------- */

.lct-tw .lct-field {
	display: flex;
	flex-direction: column;
	gap: 4px;
}
.lct-tw .lct-field-label {
	font-size: 12px;
	font-weight: 600;
	color: #374151;
}

/* =========================================================================
   v1.0.0 — Phase 2 polish
   ========================================================================= */

/* ---------- Section status pips ----------
   Visible dot at the trailing edge of each nav button, color-coded by
   progress. Empty → invisible. The base .lct-section-nav-pip rule lives
   in the layout section above; these are state overrides. */

.lct-tw .lct-section-nav-btn.has-progress .lct-section-nav-pip {
	background: #3b82f6;
	box-shadow: 0 0 0 3px rgba(59, 130, 246, .15);
}
.lct-tw .lct-section-nav-btn.has-complete .lct-section-nav-pip {
	background: #10b981;
	box-shadow: 0 0 0 3px rgba(16, 185, 129, .15);
}
.lct-tw .lct-section-nav-btn.has-warning .lct-section-nav-pip {
	background: #f59e0b;
	box-shadow: 0 0 0 3px rgba(245, 158, 11, .15);
	animation: lctPipPulse 2.4s ease-in-out infinite;
}
@keyframes lctPipPulse {
	0%, 100% { box-shadow: 0 0 0 3px rgba(245, 158, 11, .15); }
	50%      { box-shadow: 0 0 0 5px rgba(245, 158, 11, .08); }
}

/* ---------- First-paint onboarding pulse ----------
   Single-shot attention-getter on the Templates nav item. Removed
   programmatically on first click anywhere in the builder. */

@keyframes lctOnboardPulse {
	0%, 100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, .35); }
	50%      { box-shadow: 0 0 0 10px rgba(59, 130, 246, 0); }
}
.lct-tw .lct-section-nav-btn.lct-onboard-pulse {
	animation: lctOnboardPulse 2s ease-out infinite;
}
@media (prefers-reduced-motion: reduce) {
	.lct-tw .lct-section-nav-btn.lct-onboard-pulse,
	.lct-tw .lct-section-nav-btn.has-warning .lct-section-nav-pip {
		animation: none;
	}
}

/* ---------- Per-section help link ----------
   Small question-mark icon next to each panel title. Inline with the
   title text, slate-gray at rest, brand-blue on hover. */

.lct-tw .lct-section-help-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	border-radius: 9999px;
	color: #94a3b8;
	background: transparent;
	text-decoration: none;
	transition: color .15s ease, background-color .15s ease;
	margin-left: 4px;
	flex-shrink: 0;
}
.lct-tw .lct-section-help-link:hover,
.lct-tw .lct-section-help-link:focus-visible {
	color: #2563eb;
	background: #eff6ff;
}
.lct-tw .lct-section-help-link:focus-visible {
	outline: 2px solid #3b82f6;
	outline-offset: 2px;
}

/* ---------- "Next step" hint ----------
   Single-line footer at the bottom of each panel pointing the user at
   the next likely section. Subtle, slate-tinted, with an inline button
   that styles like a link. */

.lct-tw .lct-next-step {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 1.5rem;
	padding: 10px 14px;
	background: #f8fafc;
	border: 1px solid #e2e8f0;
	border-radius: 8px;
	font-size: 13px;
	color: #475569;
	line-height: 1.4;
}
.lct-tw .lct-next-step-icon {
	font-size: 14px;
	color: #2563eb;
	flex-shrink: 0;
}
.lct-tw .lct-next-step-link {
	display: inline;
	padding: 0;
	background: transparent;
	border: 0;
	color: #2563eb;
	font-weight: 600;
	cursor: pointer;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
	font-size: inherit;
}
.lct-tw .lct-next-step-link:hover,
.lct-tw .lct-next-step-link:focus-visible {
	color: #1d4ed8;
	text-decoration-thickness: 2px;
}
.lct-tw .lct-next-step-link:focus-visible {
	outline: 2px solid #93c5fd;
	outline-offset: 2px;
	border-radius: 2px;
}

/* ---------- "Saved locally" indicator ----------
   Body-level toast that pulses in the bottom-right corner each time
   state is committed to localStorage. Fades in fast, holds briefly,
   fades out gently. Pointer-events:none so it never blocks clicks. */

.lct-saved-indicator {
	position: fixed;
	bottom: 20px;
	right: 20px;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 8px 12px;
	background: #0f172a;
	color: #f1f5f9;
	border-radius: 9999px;
	font-size: 12px;
	font-weight: 500;
	box-shadow: 0 8px 24px -8px rgba(15, 23, 42, .35), 0 2px 4px rgba(15, 23, 42, .2);
	opacity: 0;
	transform: translateY(8px);
	transition: opacity .25s ease, transform .25s ease;
	pointer-events: none;
	z-index: 9999;
}
.lct-saved-indicator.is-visible {
	opacity: 1;
	transform: translateY(0);
}
.lct-saved-indicator svg {
	color: #10b981;
}
@media (prefers-reduced-motion: reduce) {
	.lct-saved-indicator {
		transition: opacity .15s linear;
		transform: none;
	}
}

/* ---------- Bottom bar ----------
   The form's command bar: the Turnstile widget (when CAPTCHA is enabled),
   the disabled-reason text, the trust copy (reassurance + privacy notice),
   and the primary Generate button. Sits in normal flow at the bottom of the
   form (NOT sticky) — the previous sticky/pinned treatment hugged the
   viewport and ate too much vertical space, so it now simply ends the
   builder and scrolls away with the rest of the content. */

.lct-tw .lct-bottom-bar {
	background: #ffffff;
	border-top: 1px solid #e5e7eb;
	margin-top: 1rem;
}
.lct-tw .lct-bottom-bar-inner {
	display: flex;
	align-items: center;
	gap: 1rem;
	padding: 10px 16px;
	flex-wrap: wrap;
	max-width: 100%;
}

/* Turnstile widget cell. The Cloudflare widget rasters at a fixed
   width (~300px) so we let it take its natural width and prevent it
   from stretching to fill leftover row space. */
.lct-tw .lct-bottom-bar-captcha {
	flex: 0 0 auto;
}

/* Trust column — reassurance + privacy notice in muted micro-type.
   Flex-1 lets it absorb the leftover horizontal space; on narrower
   widths it wraps below the captcha + submit row. */
.lct-tw .lct-bottom-bar-trust {
	flex: 1 1 200px;
	min-width: 0;
	font-size: 11px;
	line-height: 1.4;
	color: #6b7280;
}
.lct-tw .lct-bottom-bar-trust .lct-reassurance,
.lct-tw .lct-bottom-bar-trust .lct-privacy-notice {
	margin: 0;
}
.lct-tw .lct-bottom-bar-trust .lct-privacy-notice {
	margin-top: 2px;
}
.lct-tw .lct-bottom-bar-trust a {
	color: #2563eb;
	text-decoration: underline;
}
.lct-tw .lct-bottom-bar-trust a:hover {
	color: #1d4ed8;
}

/* Submit column — Generate button plus the inline disabled-reason
   text. The reason sits to the left of the button at >= 640px and
   collapses below it on narrower widths. Empty by default — the JS
   only writes a string when Generate is disabled. */
.lct-tw .lct-bottom-bar-submit {
	display: flex;
	align-items: center;
	gap: 10px;
	flex: 0 0 auto;
	flex-wrap: wrap;
	justify-content: flex-end;
}
.lct-tw .lct-bottom-bar-submit .lct-disabled-reason {
	font-size: 11px;
	line-height: 1.4;
	color: #b45309;
	max-width: 240px;
	text-align: right;
}
.lct-tw .lct-bottom-bar-submit .lct-disabled-reason:empty {
	display: none;
}

/* Narrow-viewport layout — stack the bar's columns vertically so
   the captcha, trust copy, and button each get their own row.
   Reassurance/privacy aligns left; submit row stays right-aligned. */
@media (max-width: 767px) {
	.lct-tw .lct-bottom-bar-inner {
		gap: 8px;
	}
	.lct-tw .lct-bottom-bar-captcha,
	.lct-tw .lct-bottom-bar-trust,
	.lct-tw .lct-bottom-bar-submit {
		flex: 1 1 100%;
	}
	.lct-tw .lct-bottom-bar-submit {
		justify-content: stretch;
	}
	.lct-tw .lct-bottom-bar-submit .lct-submit {
		flex: 1 1 100%;
	}
}

/* ---------- Preview frame polish ----------
   Subtle device-frame treatment. Surface inside the frame stays white
   (or slate-900 in dark mode) so email-client simulation accuracy
   isn't compromised. */

.lct-tw .lct-section-preview .lct-preview-frame {
	border: 1px solid #e5e7eb;
	border-radius: 10px;
	box-shadow: inset 0 0 0 1px rgba(15, 23, 42, .03);
	padding: 3rem 16px;
	position: relative;
	min-height: 240px;
}
.lct-tw .lct-section-preview .lct-preview-frame::before {
	content: "PREVIEW";
	position: absolute;
	top: 8px;
	left: 12px;
	font-size: 9px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: #cbd5e1;
	pointer-events: none;
	z-index: 1;
}
.lct-tw .lct-section-preview .lct-preview-frame.lct-theme-dark::before {
	color: #475569;
}

/* =========================================================================
   Email-window chrome (HubSpot-style preview frame)
   =========================================================================
   Wraps the .lct-preview-frame in a faux email-client window: Mac-style
   traffic-light buttons in a titlebar, a To / Subject meta line, and an
   abstracted body-copy block above the actual signature. Purely visual —
   nothing here reaches the exported HTML or the bulk submit payload.

   The chrome takes over the outer rounded-frame + drop-shadow treatment
   that .lct-preview-frame used to own on its own. When the chrome wraps
   the frame we strip the frame's own border + corner radius + "PREVIEW"
   pseudo-label so the chrome's titlebar reads as the canonical marker.
   The theme class (.lct-theme-light / .lct-theme-dark) is set on the
   chrome by signature-builder.js in lockstep with the preview-frame so
   the chrome darkens alongside its contents. */

.lct-tw .lct-preview-chrome {
	border: 1px solid #d1d5db;
	border-radius: 10px;
	overflow: hidden;
	box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 6px 18px -8px rgba(15, 23, 42, .08);
	background: #ffffff;
	transition: background-color .25s ease, border-color .25s ease;
}
.lct-tw .lct-preview-chrome.lct-theme-dark {
	border-color: #1f2937;
	background: #0f172a;
}

.lct-tw .lct-preview-titlebar {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 10px 12px;
	background: #3d434a;
	border-bottom: 1px solid #e5e7eb;
}
.lct-tw .lct-preview-chrome.lct-theme-dark .lct-preview-titlebar {
	background: #1e293b;
	border-bottom-color: #334155;
}
.lct-tw .lct-preview-titlebar-dot {
	display: inline-block;
	width: 11px;
	height: 11px;
	border-radius: 50%;
	background: #414549;
}
.lct-tw .lct-preview-titlebar-dot--red    { background: #ef4444; }
.lct-tw .lct-preview-titlebar-dot--yellow { background: #f59e0b; }
.lct-tw .lct-preview-titlebar-dot--green  { background: #10b981; }

.lct-tw .lct-preview-meta {
	padding: 10px 14px 12px;
	background: #ffffff;
	border-bottom: 1px solid #e5e7eb;
	font-size: 12px;
	line-height: 1.5;
	color: #374151;
	display: flex;
	flex-direction: column;
	gap: 4px;
}
.lct-tw .lct-preview-chrome.lct-theme-dark .lct-preview-meta {
	background: #0f172a;
	border-bottom-color: #334155;
	color: #cbd5e1;
}
.lct-tw .lct-preview-meta-row {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}
.lct-tw .lct-preview-meta-label {
	color: #6b7280;
	font-weight: 500;
}
.lct-tw .lct-preview-chrome.lct-theme-dark .lct-preview-meta-label {
	color: #94a3b8;
}
.lct-tw .lct-preview-recipient-pill {
	display: inline-block;
	padding: 1px 10px;
	border: 1.5px solid #14b8a6;
	border-radius: 999px;
	color: #0f766e;
	background: #ffffff;
	font-weight: 500;
	font-size: 11px;
	line-height: 1.6;
}
.lct-tw .lct-preview-chrome.lct-theme-dark .lct-preview-recipient-pill {
	background: #0f172a;
	border-color: #14b8a6;
	color: #5eead4;
}
.lct-tw .lct-preview-subject {
	font-weight: 600;
	color: #111827;
}
.lct-tw .lct-preview-chrome.lct-theme-dark .lct-preview-subject {
	color: #e5e7eb;
}

/* Abstracted body copy above the signature — two gray bars hinting at
   the mail body the recipient would read before the signature. Subtle
   enough not to compete with the actual signature for attention. */
.lct-tw .lct-preview-body-mock {
	padding: 14px 14px 4px;
	background: #ffffff;
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.lct-tw .lct-preview-chrome.lct-theme-dark .lct-preview-body-mock {
	background: #0f172a;
}
.lct-tw .lct-preview-body-mock-line {
	display: block;
	height: 8px;
	border-radius: 50px;
	background: #e5e7eb;
}
.lct-tw .lct-preview-body-mock-line:nth-child(1) { width: 70%; }
.lct-tw .lct-preview-body-mock-line:nth-child(2) { width: 50%; }
.lct-tw .lct-preview-chrome.lct-theme-dark .lct-preview-body-mock-line {
	background: #1e293b;
}

/* Inside the chrome, the preview-frame drops its own outer border,
   shadow, rounded corners, and "PREVIEW" pseudo-label — the chrome
   owns those now. Padding is tightened (the meta block above provides
   the breathing room a stand-alone frame used to bake in). */
.lct-tw .lct-preview-chrome .lct-preview-frame {
	border: 0;
	border-radius: 0;
	box-shadow: none;
	padding: 16px;
	min-height: 0;
}
.lct-tw .lct-preview-chrome .lct-preview-frame::before {
	content: none;
}

/* When the inspector is sticky (>= 1024px), cap the preview frame's
   height and scroll INTERNALLY when the signature exceeds the cap.
   The chrome titlebar + To/Subject + body-mock stay pinned above;
   only the signature body scrolls. Mirrors how a real email client
   keeps the message metadata visible while the body scrolls.
   The 460px figure accounts for: top sticky offset (~16px), card
   padding (~48px), card header + mode toggle + optional nav row
   (~120px), chrome titlebar + meta + body-mock (~130px), tertiary
   actions row + gap (~56px), bottom bar (~80px), buffer (~10px).
   On a 1080p viewport the frame ends up around 620px — large enough
   for most signatures without scroll; on a 768p laptop ~308px, where
   the internal scroll actually starts doing useful work. */
@media (min-width: 1024px) {
	.lct-tw .lct-preview-chrome .lct-preview-frame {
		min-height: 240px;
		overflow-y: auto;
	}
}

/* Reduced-motion users opt out of the background fade. */
@media (prefers-reduced-motion: reduce) {
	.lct-tw .lct-preview-chrome {
		transition: none;
	}
}
