/**
* modern.css — modern theme role-token overrides (deep theming)
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* The production "modern" theme: vibrant glassmorphism. A neon-accented
* contemporary look — bright neutral (light) / deep midnight slate (dark)
* surfaces, an electric INDIGO primary (#4F46E5) with a FUCHSIA secondary
* pop (#D946EF), Plus Jakarta Sans display sans. Highly rounded squircle
* corners (12–24px), multi-layered soft blur shadows, ambient indigo glow,
* and real glassmorphism in dark mode (translucent #1E293B surfaces +
* `--surface-blur` backdrop-filter on `.tile`). 300ms standard-ease motion.
* Modern-light is the app default; the DARK block is the midnight-glass hero.
*
* Fuchsia rides on brand-secondary + status (gradient/pop), NOT on a
* white-text fill — text-on-brand (white) reads over the indigo brand-primary
* and brand-accent (≥AA, verified via contrast.js).
*
* Activated by the runtime gate (dt-runtime), which sets `data-theme` and
* `data-mode` on <html>. See knowledge-base/style/.
*
* @version 2026-Jun-19 Vibrant glassmorphism (indigo/fuchsia, Plus Jakarta Sans) — was the greyscale pass
* @version 2026-August-10 --surface-brandmark minted for the payments panel card-brand plate — identical in every theme and mode by design
* @version 2026-August-14 --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status minted for ink on the success fill (#1840)
*/

:root[data-theme="modern"] {
	--surface-page: #FAFAFC;
	--surface-card: #F1F5F9;
	--surface-raised: #FFFFFF;
	--surface-sunken: #E9EEF4;
	--surface-hover: #EEF2F7;
	--surface-selected: #E2E8F0;
	--surface-overlay: rgba(15, 23, 42, 0.45);
	--surface-brandmark: #FFFFFF;
	--surface-blur: none;

	--brand-primary: #4F46E5;
	--brand-secondary: #D946EF;
	--brand-accent: #4F46E5;

	--text-primary: #0F172A;
	--text-secondary: #475569;
	--text-on-brand: #FFFFFF;
	--text-on-status: #0F172A;
	--text-disabled: #6F84A0;
	--text-link: #4F46E5;

	--border-default: rgba(15, 23, 42, 0.10);
	--border-strong: rgba(15, 23, 42, 0.18);
	--border-width: .1rem;

	--status-success: #10B981;
	--status-warning: #F59E0B;
	--status-danger: #EF4444;
	--status-partial: #D946EF;
	--status-info: #4F46E5;

	--focus-ring-color: #4F46E5;

	--font-display: 'Plus Jakarta Sans', 'Inter', system-ui, sans-serif;
	--font-body: 'Plus Jakarta Sans', 'Inter', system-ui, sans-serif;
	--font-mono: 'Space Mono', ui-monospace, monospace;

	/* Shapes — highly rounded squircle corners (12–24px). */
	--radius-input: 1.2rem;
	--radius-button: 1.2rem;
	--radius-card: 2rem;
	--radius-pill: 9999px;
	--radius-sheet: 2.4rem;

	/* Depth — multi-layered soft blur shadows + ambient indigo glow. */
	--shadow-dark-source: rgba(15, 23, 42, 0.10);
	--elevation-raised: 0 2rem 2.5rem -0.5rem rgba(15, 23, 42, 0.10), 0 1rem 1rem -0.5rem rgba(15, 23, 42, 0.04);
	--elevation-overlay: 0 2.4rem 4.8rem -1.2rem rgba(15, 23, 42, 0.25);
	--elevation-inset: inset 0 .1rem .2rem rgba(15, 23, 42, 0.06);
	--elevation-glow: 0 0 2rem .1rem rgba(99, 102, 241, 0.35);

	/* Motion — 300ms standard cubic-bezier (matches the spec curve). */
	--motion-base: 300ms;

}

:root[data-theme="modern"][data-mode="dark"] {
	--surface-page: #0B0F19;
	--surface-card: rgba(30, 41, 59, 0.60);
	--surface-raised: rgba(30, 41, 59, 0.75);
	--surface-sunken: rgba(15, 23, 42, 0.60);
	--surface-hover: rgba(99, 102, 241, 0.12);
	--surface-selected: rgba(99, 102, 241, 0.20);
	--surface-overlay: rgba(2, 4, 10, 0.70);
	--surface-brandmark: #FFFFFF;
	/* Glassmorphism — translucent surfaces blurred behind the content. */
	--surface-blur: blur(12px);

	--brand-primary: #4F46E5;
	--brand-secondary: #D946EF;
	--brand-accent: #4F46E5;

	--text-primary: #F8FAFC;
	--text-secondary: #94A3B8;
	--text-on-brand: #FFFFFF;
	--text-disabled: #677C98;
	--text-link: #818CF8;

	--border-default: rgba(148, 163, 184, 0.18);
	--border-strong: rgba(148, 163, 184, 0.32);
	--border-width: .1rem;

	--status-success: #34D399;
	--status-warning: #FBBF24;
	--status-danger: #F87171;
	--status-partial: #E879F9;
	--status-info: #818CF8;

	--focus-ring-color: #4F46E5;

	--font-display: 'Plus Jakarta Sans', 'Inter', system-ui, sans-serif;
	--font-body: 'Plus Jakarta Sans', 'Inter', system-ui, sans-serif;
	--font-mono: 'Space Mono', ui-monospace, monospace;

	/* Shapes — same squircle corners. */
	--radius-input: 1.2rem;
	--radius-button: 1.2rem;
	--radius-card: 2rem;
	--radius-pill: 9999px;
	--radius-sheet: 2.4rem;

	/* Depth — deep multi-layer shadows + ambient indigo glow on the void. */
	--shadow-dark-source: rgba(0, 0, 0, 0.50);
	--elevation-raised: 0 2rem 2.5rem -0.5rem rgba(0, 0, 0, 0.50), 0 1rem 1rem -0.5rem rgba(0, 0, 0, 0.30);
	--elevation-overlay: 0 2.4rem 4.8rem -1.2rem rgba(0, 0, 0, 0.65);
	--elevation-inset: inset 0 .1rem .2rem rgba(0, 0, 0, 0.30);
	--elevation-glow: 0 0 2.4rem .1rem rgba(99, 102, 241, 0.50);

	--motion-base: 300ms;

}

/**
* cyber.css — cyber theme role-token overrides (deep theming)
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* The production "cyber" theme: synthwave neon. Deep indigo-navy void,
* translucent cards, magenta + electric blue dual-neon over an indigo
* mid-tone, glow elevation, Orbitron display. Dark is the real theme;
* light is a muted daytime grid. Palette (user-supplied pixel-art ref):
*   #5c58b6 indigo · #b957ce magenta · #5994ce blue · #3a4e93 navy.
*
* `--elevation-glow` is a full box-shadow string authored to reference the
* neon (magenta + blue) directly so it does NOT desaturate through the
* neutral shadow casters. `--surface-clip` is the themeable clip-path that
* frames the one remaining structural element (getPillBox's cyber neon
* frame); flat elements ignore it.
*
* text-on-brand must read over BOTH brand-primary and brand-accent (one ink,
* two fills): dark mode pairs the bright neon fills with dark ink; light mode
* pairs deep fills with white ink — both ≥AA (verified via contrast.js).
*
* Activated by the runtime gate (dt-runtime): `data-theme="cyber"`
* (+ `data-mode="dark"`) on <html>. See knowledge-base/style/.
*
* @version 2026-Jun-19 Synthwave palette (was the cyan cyber-tron pass)
* @version 2026-August-10 --surface-brandmark minted for the payments panel card-brand plate — identical in every theme and mode by design
* @version 2026-August-14 --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status minted for ink on the success fill (#1840)
*/

:root[data-theme="cyber"] {
	--surface-page: #EEEDF7;
	--surface-card: rgba(255, 255, 255, 0.75);
	--surface-raised: rgba(255, 255, 255, 0.85);
	--surface-sunken: rgba(92, 88, 182, 0.08);
	--surface-hover: rgba(92, 88, 182, 0.10);
	--surface-selected: rgba(185, 87, 206, 0.16);
	--surface-overlay: rgba(20, 18, 45, 0.55);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #5C58B6;
	--brand-secondary: #3A4E93;
	--brand-accent: #9B3FB0;

	--text-primary: #1A1A3A;
	--text-secondary: #5C5A7E;
	/* White ink on the deep indigo/magenta fills — both ≥AA. */
	--text-on-brand: #FFFFFF;
	--text-on-status: #1A1A3A;
	--text-disabled: #7975A0;
	--text-link: #5C58B6;

	--border-default: rgba(92, 88, 182, 0.30);
	--border-strong: rgba(92, 88, 182, 0.55);
	--border-width: .1rem;

	--status-success: #2BB39A;
	--status-warning: #C77F2E;
	--status-danger: #D63B63;
	--status-partial: #9B3FB0;
	--status-info: #3A4E93;

	--focus-ring-color: #5C58B6;

	--font-display: 'Orbitron', 'Courier New', sans-serif;
	--font-body: 'Orbitron', system-ui, sans-serif;
	--font-mono: 'Space Mono', 'Courier New', monospace;

	/* Brand-keyed glow (does NOT consume the neutral shadow casters). */
	--elevation-glow: 0 0 .8rem .1rem rgba(92, 88, 182, 0.40);
	/* Neon pill frame geometry (consumed by the one structural selector). */
	--surface-clip: polygon(0 0, calc(100% - 1.2rem) 0, 100% 1.2rem, 100% 100%, 1.2rem 100%, 0 calc(100% - 1.2rem));

}

:root[data-theme="cyber"][data-mode="dark"] {
	--surface-page: #0A0A1F;
	--surface-card: rgba(58, 78, 147, 0.22);
	--surface-raised: rgba(92, 88, 182, 0.30);
	--surface-sunken: rgba(185, 87, 206, 0.07);
	--surface-hover: rgba(185, 87, 206, 0.12);
	--surface-selected: rgba(185, 87, 206, 0.20);
	--surface-overlay: rgba(5, 5, 18, 0.72);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #B957CE;
	--brand-secondary: #5C58B6;
	--brand-accent: #5994CE;

	--text-primary: #E6E3F7;
	--text-secondary: #9B95C5;
	/* Dark ink on the bright magenta/blue neon fills — both ≥AA. */
	--text-on-brand: #0B0A1E;
	--text-disabled: #7D77A5;
	--text-link: #7FB0E8;

	--border-default: rgba(123, 116, 200, 0.30);
	--border-strong: rgba(143, 120, 220, 0.55);
	--border-width: .1rem;

	--status-success: #4FD3B0;
	--status-warning: #E0A24E;
	--status-danger: #FF5C8A;
	--status-partial: #B957CE;
	--status-info: #5994CE;

	--focus-ring-color: #B957CE;

	--font-display: 'Orbitron', 'Courier New', sans-serif;
	--font-body: 'Orbitron', system-ui, sans-serif;
	--font-mono: 'Space Mono', 'Courier New', monospace;

	--elevation-glow: 0 0 1rem .1rem rgba(185, 87, 206, 0.55), inset 0 0 1rem rgba(89, 148, 206, 0.20);
	--surface-clip: polygon(0 0, calc(100% - 1.2rem) 0, 100% 1.2rem, 100% 100%, 1.2rem 100%, 0 calc(100% - 1.2rem));

}

/* ---------------------------------------------------------------------------
 * Cyber structural frame — ported from the de-baked baseElements
 * `.pillBox-CYBER_THEME` / `.tile-CYBER_THEME` blocks (getPillBox/getTile no
 * longer emit a per-theme class). The geometry (angular clip-path + the
 * ::before fill layer + the ::after neon stroke) is theme STRUCTURE and lives
 * here under the `data-theme="cyber"` gate, not in shared baseElements.css.
 * Colours stay customizable role tokens (--surface-card / --brand-accent /
 * --surface-blur, themselves set to the cyber palette in this file), so
 * per-entity customization still flows through. Overrides the flat
 * `--surface-clip` clip on `.pillBox` with the elaborate two-layer frame.
 * ------------------------------------------------------------------------- */
:root[data-theme="cyber"] .pillBox {
	position: relative;
	overflow: hidden;
	clip-path: polygon(0 0, calc(100% - 25px) 0, 100% 25px, 100% 100%, 0 100%);
}

:root[data-theme="cyber"] .pillBox>* {
	position: relative;
}

:root[data-theme="cyber"] .pillBox::before {
	content: '';
	position: absolute;
	inset: 0;
	clip-path: polygon(0 0, calc(100% - 25px) 0, 100% 25px, 100% 100%, 0 100%);
	background: var(--surface-card);
	backdrop-filter: var(--surface-blur);
	z-index: 0;
}

:root[data-theme="cyber"] .pillBox::after {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: var(--brand-accent);
	clip-path: polygon(0 0, calc(100% - 25px) 0, 100% 25px, 100% 100%, 0 100%, 0 0, 2px 2px, 2px calc(100% - 2px), calc(100% - 2px) calc(100% - 2px), calc(100% - 2px) 26px, calc(100% - 26px) 2px, 2px 2px);
}

:root[data-theme="cyber"] .tile {
	position: relative;
}

:root[data-theme="cyber"] .tile::after {
	content: '';
	position: absolute;
	background-color: currentColor;
	clip-path: polygon(1px 1px, 0% 0%, 0% 100%, 100% 100%, 100% 20px, calc(100% - 20px) 0%,
			0% 0%, 1px 1px, calc(100% - 21px) 1px, calc(100% - 1px) 21px, calc(100% - 1px) calc(100% - 1px),
			1px calc(100% - 1px));
	height: 100%;
	width: 100%;
	opacity: .4;
	transition: inherit;
}
/**
* futuristic.css — futuristic theme role-token overrides (deep theming)
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* The production "futuristic" theme: the live-demo dark cyan-neon look
* (near-black void #0A0A14, electric cyan #54EAFD brand, Audiowide display
* over a system body/mono stack, crisp radius, cyan-tinted glow). Per the
* user's roster decision this follows the DEMO, NOT the typeui doc's
* light-corporate spec — and is DISTINCT from cyber: cyber is cyan-on-navy
* glass with Orbitron + a clip-path frame; futuristic is cyan-on-black flat
* with Audiowide + crisp small radii and no clip frame.
*
* `--elevation-glow` is a brand-keyed cyan glow string (references the cyan
* directly so the neon stays saturated). Crisp `--radius-*` overrides give
* the sharp futuristic edges.
*
* Activated by the runtime gate (dt-runtime): `data-theme="futuristic"`
* (+ `data-mode="dark"`) on <html>. Values re-derived from
* styleBoard/palettes.js (`futuristic` preset). See knowledge-base/style/.
*
* @version 2026-Jun-19 Initial deep-theming version
* @version 2026-July-29 Radius overrides snapped to the catalog's 0.1rem step grid
*                       (.25rem → .3rem, light + dark) so the customize panel's
*                       slider can return to the theme's own default.
* @version 2026-August-10 --surface-brandmark minted for the payments panel card-brand plate — identical in every theme and mode by design
* @version 2026-August-14 --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status minted for ink on the success fill (#1840)
*/

:root[data-theme="futuristic"] {
	--surface-page: #EEF2F6;
	--surface-card: #FFFFFF;
	--surface-raised: #FFFFFF;
	--surface-sunken: #E3EAF0;
	--surface-hover: rgba(16, 158, 178, 0.08);
	--surface-selected: rgba(16, 158, 178, 0.14);
	--surface-overlay: rgba(8, 12, 24, 0.50);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #0FA9BD;
	--brand-secondary: #1C7FB8;
	--brand-accent: #0FA9BD;

	--text-primary: #111827;
	--text-secondary: #5B6472;
	/* Dark ink on the light cyan brand fill — white was 2.83:1 (AA-fail/invisible). */
	--text-on-brand: #04121A;
	--text-on-status: #111827;
	--text-disabled: #737F92;
	--text-link: #0FA9BD;

	--border-default: rgba(15, 169, 189, 0.24);
	--border-strong: rgba(15, 169, 189, 0.50);
	--border-width: .1rem;

	--status-success: #00C853;
	--status-warning: #E0A800;
	--status-danger: #E5003C;
	--status-partial: #2BB8A0;
	--status-info: #1C7FB8;

	/* Deepened from #0FA9BD (2.51:1 on the light page — failed WCAG 1.4.11/2.4.11
	   3:1 for non-text UI) to meet the contrast gate; 3.89:1 on --surface-page. */
	--focus-ring-color: #0C8595;

	--font-display: 'Audiowide', 'Orbitron', system-ui, sans-serif;
	--font-body: system-ui, 'Segoe UI', Roboto, sans-serif;
	--font-mono: ui-monospace, 'Courier New', monospace;

	/* Crisp futuristic edges. */
	--radius-input: .3rem;
	--radius-button: .3rem;
	--radius-card: .4rem;

	--elevation-glow: 0 0 1rem .1rem rgba(15, 169, 189, 0.30);

}

:root[data-theme="futuristic"][data-mode="dark"] {
	--surface-page: #0A0A14;
	--surface-card: #12121F;
	--surface-raised: #16162A;
	--surface-sunken: #08080F;
	--surface-hover: rgba(84, 234, 253, 0.08);
	--surface-selected: rgba(84, 234, 253, 0.16);
	--surface-overlay: rgba(2, 2, 8, 0.72);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #54EAFD;
	--brand-secondary: #3AB4FF;
	--brand-accent: #54EAFD;

	--text-primary: #F0F0F8;
	--text-secondary: #999AAB;
	--text-on-brand: #04121A;
	--text-disabled: #777C96;
	--text-link: #54EAFD;

	--border-default: rgba(84, 234, 253, 0.22);
	--border-strong: rgba(84, 234, 253, 0.50);
	--border-width: .1rem;

	--status-success: #00E676;
	--status-warning: #FFD600;
	--status-danger: #FF003C;
	--status-partial: #5FE3C7;
	--status-info: #3AB4FF;

	--focus-ring-color: #54EAFD;

	--font-display: 'Audiowide', 'Orbitron', system-ui, sans-serif;
	--font-body: system-ui, 'Segoe UI', Roboto, sans-serif;
	--font-mono: ui-monospace, 'Courier New', monospace;

	--radius-input: .3rem;
	--radius-button: .3rem;
	--radius-card: .4rem;

	--elevation-glow: 0 1.4rem 2rem -.4rem rgba(84, 234, 253, 0.18), 0 0 1rem rgba(84, 234, 253, 0.25);

}

/**
* neumorphism.css — neumorphism theme role-token overrides (deep theming)
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
* @version 2026-Jun-19 Initial deep-theming version
* @version 2026-August-10 --surface-brandmark minted for the payments panel card-brand plate — identical in every theme and mode by design
*
* The production "neumorphism" theme: soft extruded UI. Cards are the SAME
* color as the page — depth comes entirely from dual light/dark caster
* shadows, not fill or border. Teal accent, Space Mono display / Quicksand
* body, `--border-width:0`. Raised idle / inset pressed, both expressed
* purely as `--elevation-*` box-shadow VALUE tokens built from the two
* caster colors (`--shadow-light-source` / `--shadow-dark-source`), so
* light↔dark is a two-color flip and the whole scale follows — zero
* per-component CSS.
*
* ACCESSIBILITY COMPROMISES (the theme IS the compromise, deliberate, not a
* toggle). Same-material surfaces fail non-color contrast heuristics, so:
*   1. `--border-default` keeps a faint HAIRLINE (not transparent) so
*      interactive boundaries are perceivable under prefers-contrast/forced
*      colors and for low-vision users — even though the aesthetic is
*      "borderless". `--border-width` stays 0 (the hairline shows only where
*      a 1px boundary is explicitly applied / under contrast media queries).
*   2. Primary buttons get a REAL brand fill (`--brand-primary`), not a flat
*      same-material surface, so the primary action is unambiguous.
*   3. The focus-visible ring is NEVER suppressed — it is shadow-independent
*      (real outline) so keyboard focus survives the soft-shadow look.
* The `prefers-contrast: more` / `forced-colors` fallback below makes the
* hairline a solid 1px boundary.
*
* Activated by the runtime gate (dt-runtime): `data-theme="neumorphism"`
* (+ `data-mode="dark"`) on <html>. Values re-derived from
* styleBoard/palettes.js (`neumorph` preset). See knowledge-base/style/.
*
* @version 2026-August-14 --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status minted for ink on the success fill (#1840)
*/

:root[data-theme="neumorphism"] {
	/* Single-material surface — page, card, raised, sunken all share one color. */
	--surface-page: #E6EBEA;
	--surface-card: #E6EBEA;
	--surface-raised: #E6EBEA;
	--surface-sunken: #E6EBEA;
	--surface-hover: #DDE3E1;
	--surface-selected: #D4DBD9;
	--surface-overlay: rgba(45, 58, 56, 0.40);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #006666;
	--brand-secondary: #5FC2B6;
	--brand-accent: #2F8A80;

	--text-primary: #2D3A38;
	--text-secondary: #56605E;
	--text-on-brand: #FFFFFF;
	--text-on-status: #0F0F12;
	--text-disabled: #6C7C78;
	--text-link: #006666;

	/* A11y compromise 1: faint hairline (NOT transparent) for perceivable
	   boundaries; width stays 0 for the borderless aesthetic. */
	--border-default: rgba(45, 58, 56, 0.10);
	--border-strong: rgba(45, 58, 56, 0.18);
	--border-width: 0;

	--status-success: #2F8A80;
	--status-warning: #D98E4E;
	--status-danger: #E06A6A;
	--status-partial: #D98AA0;
	--status-info: #3FB6A8;

	--focus-ring-color: #006666;

	--font-display: 'Space Mono', 'Quicksand', system-ui, sans-serif;
	--font-body: 'Quicksand', system-ui, sans-serif;
	--font-mono: 'Space Mono', 'Courier New', monospace;

	/* Dual-caster shadow sources — the whole raised/inset scale is built
	   from these two colors; flip them for dark mode. */
	--shadow-light-source: #ffffff;
	--shadow-dark-source: #c4ccca;
	--elevation-raised: 0.6rem 0.6rem 1.2rem var(--shadow-dark-source), -0.6rem -0.6rem 1.2rem var(--shadow-light-source);
	--elevation-overlay: 0.9rem 0.9rem 1.8rem var(--shadow-dark-source), -0.9rem -0.9rem 1.8rem var(--shadow-light-source);
	--elevation-inset: inset 0.3rem 0.3rem 0.6rem var(--shadow-dark-source), inset -0.3rem -0.3rem 0.6rem var(--shadow-light-source);
	--elevation-button: var(--elevation-raised);

}

:root[data-theme="neumorphism"][data-mode="dark"] {
	--surface-page: #2A2F2E;
	--surface-card: #2A2F2E;
	--surface-raised: #2A2F2E;
	--surface-sunken: #2A2F2E;
	--surface-hover: #313736;
	--surface-selected: #383F3D;
	--surface-overlay: rgba(0, 0, 0, 0.55);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #3FB6A8;
	--brand-secondary: #6FE0D2;
	--brand-accent: #3FB6A8;

	--text-primary: #DCE4E2;
	--text-secondary: #A1ACA9;
	--text-on-brand: #0E1413;
	--text-on-status: #2D3A38;
	--text-disabled: #7D8D8A;
	--text-link: #3FB6A8;

	--border-default: rgba(220, 228, 226, 0.10);
	--border-strong: rgba(220, 228, 226, 0.16);
	--border-width: 0;

	--status-success: #3FB6A8;
	--status-warning: #D98E4E;
	--status-danger: #E06A6A;
	--status-partial: #D98AA0;
	--status-info: #3FB6A8;

	--focus-ring-color: #3FB6A8;

	--font-display: 'Space Mono', 'Quicksand', system-ui, sans-serif;
	--font-body: 'Quicksand', system-ui, sans-serif;
	--font-mono: 'Space Mono', 'Courier New', monospace;

	/* Casters flip for dark — the raised/inset formulas are unchanged. */
	--shadow-light-source: #343b3a;
	--shadow-dark-source: #202423;
	--elevation-raised: 0.6rem 0.6rem 1.2rem var(--shadow-dark-source), -0.6rem -0.6rem 1.2rem var(--shadow-light-source);
	--elevation-overlay: 0.9rem 0.9rem 1.8rem var(--shadow-dark-source), -0.9rem -0.9rem 1.8rem var(--shadow-light-source);
	--elevation-inset: inset 0.3rem 0.3rem 0.6rem var(--shadow-dark-source), inset -0.3rem -0.3rem 0.6rem var(--shadow-light-source);
	--elevation-button: var(--elevation-raised);

}

/* A11y compromise: under high-contrast / forced-colors, promote the faint
   hairline to a solid 1px boundary so interactive edges are unambiguous. */
@media (prefers-contrast: more) {
	:root[data-theme="neumorphism"],
	:root[data-theme="neumorphism"][data-mode="dark"] {
		--border-width: .1rem;
		--border-default: var(--border-strong);
	}
}

@media (forced-colors: active) {
	:root[data-theme="neumorphism"],
	:root[data-theme="neumorphism"][data-mode="dark"] {
		--border-width: .1rem;
	}
}

/**
* retro.css — retro theme role-token overrides (deep theming)
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* The production "retro" theme: nostalgic print. Warm off-white paper
* surfaces, serif type (Fraunces display), thin ink hairlines, FLAT (almost
* no shadow — hairline offsets only), one vintage red accent. Purely
* token-expressible — no per-component CSS, no structural variant (unlike
* cyber's clip frame). Activated by the runtime gate (dt-runtime):
* `data-theme="retro"` (+ `data-mode="dark"`) on <html>. Values from
* styleBoard/palettes.js (`retro` preset). `:root[...]` specificity so the
* theme block beats the `:root` modern floor at the same source order.
*
* @version 2026-Jun-19 Initial deep-theming version
* @version 2026-August-10 --surface-brandmark minted for the payments panel card-brand plate — identical in every theme and mode by design
* @version 2026-August-14 --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status minted for ink on the success fill (#1840)
*/

:root[data-theme="retro"] {
	--surface-page: #F2F1EC;
	--surface-card: #FBFAF6;
	--surface-raised: #FBFAF6;
	--surface-sunken: #E5E2D8;
	--surface-hover: #ECEAE2;
	--surface-selected: #E5E2D8;
	--surface-overlay: rgba(26, 26, 26, 0.45);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #C0392B;
	--brand-secondary: #6E6A60;
	--brand-accent: #C0392B;

	--text-primary: #1A1A1A;
	--text-secondary: #67635A;
	--text-on-brand: #FBFAF6;
	--text-on-status: #FFFFFF;
	--text-disabled: #847E6F;
	--text-link: #C0392B;

	--border-default: rgba(26, 26, 26, 0.20);
	--border-strong: rgba(26, 26, 26, 0.40);
	--border-width: .1rem;

	--status-success: #5A7D3C;
	--status-warning: #B8862F;
	--status-danger: #C0392B;
	--status-partial: #C57A6A;
	--status-info: #6E6A60;

	--focus-ring-color: #C0392B;

	--font-display: 'Fraunces', Georgia, serif;
	--font-body: Georgia, 'Times New Roman', serif;
	--font-mono: 'Courier New', monospace;

	/* Flat — hairline offset shadows only; buttons stay flat (no --elevation-button override). */
	--elevation-raised: 0 0.1rem 0 rgba(26, 26, 26, 0.10);
	--elevation-overlay: 0 0.2rem 0 rgba(26, 26, 26, 0.16);
	--elevation-inset: inset 0 0.1rem 0.1rem rgba(26, 26, 26, 0.08);

}

:root[data-theme="retro"][data-mode="dark"] {
	--surface-page: #1E1C18;
	--surface-card: #26241F;
	--surface-raised: #26241F;
	--surface-sunken: #161410;
	--surface-hover: #2C2925;
	--surface-selected: #34302A;
	--surface-overlay: rgba(0, 0, 0, 0.55);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #E2674F;
	--brand-secondary: #A8A294;
	--brand-accent: #E2674F;

	--text-primary: #F2F1EC;
	--text-secondary: #A8A294;
	--text-on-brand: #1E1C18;
	--text-on-status: #1A1A1A;
	--text-disabled: #807B6D;
	--text-link: #E2674F;

	--border-default: rgba(242, 241, 236, 0.18);
	--border-strong: rgba(242, 241, 236, 0.36);
	--border-width: .1rem;

	--status-success: #7FA856;
	--status-warning: #D9A24E;
	--status-danger: #E2674F;
	--status-partial: #D98A78;
	--status-info: #A8A294;

	--focus-ring-color: #E2674F;

	--font-display: 'Fraunces', Georgia, serif;
	--font-body: Georgia, 'Times New Roman', serif;
	--font-mono: 'Courier New', monospace;

	--elevation-raised: 0 0.1rem 0 rgba(0, 0, 0, 0.30);
	--elevation-overlay: 0 0.2rem 0 rgba(0, 0, 0, 0.40);
	--elevation-inset: inset 0 0.1rem 0.1rem rgba(0, 0, 0, 0.25);

}

/**
* ember.css — ember theme role-token overrides (deep theming)
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* The production "ember" theme: graduated from the cyber-ember candidate.
* The cyber glass base — deep void, translucent cards, neon pill clip frame,
* glow elevation, Space Mono — but a warm EMBER amber accent instead of pure
* cyan (the CLU-vs-Tron contrast). Brand stays cyan; accent (buttons/sliders/
* pills/focus) goes ember. Dark is the real theme; light is a muted day grid.
*
* `--elevation-glow` references the ember amber directly so the neon does not
* desaturate through the neutral casters. `--surface-clip` frames the one
* structural element (getPillBox's neon frame); flat elements ignore it.
*
* text-on-brand reads over BOTH brand-primary (cyan) and brand-accent (amber):
* dark mode pairs the bright fills with dark ink; light mode also uses dark ink
* (white was 2.48:1 on the light cyan — AA-fail) — both ≥AA.
*
* Activated by the runtime gate (dt-runtime): `data-theme="ember"`
* (+ `data-mode="dark"`) on <html>. See knowledge-base/style/.
*
* @version 2026-Jun-19 Graduated from styleBoard cyber-ember candidate
* @version 2026-August-10 --surface-brandmark minted for the payments panel card-brand plate — identical in every theme and mode by design
* @version 2026-August-14 --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status minted for ink on the success fill; --focus-ring-color deepened from #E0853A (2.31:1 on this theme's page — the widened gate's one new focus finding) (#1840)
*/

:root[data-theme="ember"] {
	--surface-page: #EEEAE4;
	--surface-card: rgba(255, 255, 255, 0.70);
	--surface-raised: rgba(255, 255, 255, 0.78);
	--surface-sunken: rgba(224, 133, 58, 0.08);
	--surface-hover: rgba(224, 133, 58, 0.10);
	--surface-selected: rgba(224, 133, 58, 0.16);
	--surface-overlay: rgba(24, 16, 8, 0.55);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #0FB5C9;
	--brand-secondary: #E0853A;
	--brand-accent: #E0853A;

	--text-primary: #241B14;
	--text-secondary: #6C5E4F;
	/* Dark ink — white was 2.48:1 on the light cyan / amber fills (AA-fail). */
	--text-on-brand: #18120A;
	--text-on-status: #241B14;
	--text-disabled: #8B7866;
	--text-link: #0FB5C9;

	--border-default: rgba(224, 133, 58, 0.30);
	--border-strong: rgba(224, 133, 58, 0.55);
	--border-width: .1rem;

	--status-success: #2BB8A0;
	--status-warning: #E0853A;
	--status-danger: #E5466B;
	--status-partial: #2BB8A0;
	--status-info: #0FB5C9;

	--focus-ring-color: #C96C20;

	--font-display: 'Space Mono', 'Courier New', monospace;
	--font-body: 'Space Mono', monospace;
	--font-mono: 'Space Mono', 'Courier New', monospace;

	/* Ember-keyed glow (does NOT consume the neutral shadow casters). */
	--elevation-glow: 0 0 .8rem .1rem rgba(224, 133, 58, 0.45);
	/* Neon pill frame geometry (consumed by the one structural selector). */
	--surface-clip: polygon(0 0, calc(100% - 1.2rem) 0, 100% 1.2rem, 100% 100%, 1.2rem 100%, 0 calc(100% - 1.2rem));

}

:root[data-theme="ember"][data-mode="dark"] {
	--surface-page: #0A0810;
	--surface-card: rgba(30, 24, 40, 0.55);
	--surface-raised: rgba(40, 32, 52, 0.65);
	--surface-sunken: rgba(255, 157, 61, 0.06);
	--surface-hover: rgba(255, 157, 61, 0.12);
	--surface-selected: rgba(255, 157, 61, 0.18);
	--surface-overlay: rgba(4, 2, 8, 0.70);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #25D8EC;
	--brand-secondary: #FF9D3D;
	--brand-accent: #FF9D3D;

	--text-primary: #F0E6DC;
	--text-secondary: #AA9481;
	--text-on-brand: #1A0F06;
	--text-disabled: #8B7662;
	--text-link: #25D8EC;

	--border-default: rgba(255, 157, 61, 0.30);
	--border-strong: rgba(255, 157, 61, 0.55);
	--border-width: .1rem;

	--status-success: #5FE3C7;
	--status-warning: #FFB347;
	--status-danger: #FF5C7A;
	--status-partial: #5FE3C7;
	--status-info: #25D8EC;

	--focus-ring-color: #FF9D3D;

	--font-display: 'Space Mono', 'Courier New', monospace;
	--font-body: 'Space Mono', monospace;
	--font-mono: 'Space Mono', 'Courier New', monospace;

	--elevation-glow: 0 0 1rem .1rem rgba(255, 157, 61, 0.55), inset 0 0 1rem rgba(255, 157, 61, 0.25);
	--surface-clip: polygon(0 0, calc(100% - 1.2rem) 0, 100% 1.2rem, 100% 100%, 1.2rem 100%, 0 calc(100% - 1.2rem));

}

/**
* elegant.css — elegant theme role-token overrides (deep theming)
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* The production "elegant" theme: old-money / quiet-luxury. A disciplined
* three-colour palette — deep OLIVE green, CREAM, ESPRESSO brown — over a
* classic high-contrast serif (Playfair Display) display with a Manrope sans
* body. Cream surfaces, olive brand, espresso ink + accents, oxblood danger.
* Tailored architectural corners + a restrained letterpress depth (warm
* ink-tinted, low-spread — the hairline border separates, the shadow whispers).
* The DARK block layers the espresso night palette (warm near-black, lifted
* olive + caramel). Graduated from the original "modern" old-money pass.
*
* text-on-brand must read over BOTH brand-primary (olive) and brand-accent
* (espresso): light pairs the deep fills with cream ink; dark pairs the lifted
* fills with espresso ink — both ≥AA (verified via contrast.js).
*
* Activated by the runtime gate (dt-runtime), which sets `data-theme` and
* `data-mode` on <html>. See knowledge-base/style/.
*
* @version 2026-Jun-19 Initial deep-theming version (was the modern old-money pass)
* @version 2026-August-10 --surface-brandmark minted for the payments panel card-brand plate — identical in every theme and mode by design
* @version 2026-August-14 --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status minted for ink on the success fill (#1840)
*/

:root[data-theme="elegant"] {
	--surface-page: #F2EDE1;
	--surface-card: #FAF6EC;
	--surface-raised: #FFFDF6;
	--surface-sunken: #E8E1D0;
	--surface-hover: #EDE7D8;
	--surface-selected: #E0D7C2;
	--surface-overlay: rgba(46, 33, 26, 0.45);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #4F5526;
	--brand-secondary: #5C4433;
	--brand-accent: #5C4433;

	--text-primary: #2E211A;
	--text-secondary: #6B5848;
	/* Cream ink on the deep olive/espresso fills — both ≥AA. */
	--text-on-brand: #F5EFE2;
	--text-on-status: #FFFFFF;
	--text-disabled: #857561;
	--text-link: #4F5526;

	--border-default: rgba(46, 33, 26, 0.16);
	--border-strong: rgba(46, 33, 26, 0.34);
	--border-width: .1rem;

	--status-success: #5A7D3C;
	--status-warning: #B8862F;
	--status-danger: #8C3A33;
	--status-partial: #A8763C;
	--status-info: #5E6B66;

	--focus-ring-color: #4F5526;

	/* Shapes — tailored, architectural corners (engraved-invitation, not bubbly).
	   Tighter than the playful floor; pills become editorial chips, not lozenges. */
	--radius-input: .3rem;
	--radius-button: .3rem;
	--radius-card: .6rem;
	--radius-pill: .4rem;
	--radius-sheet: .8rem;

	/* Depth — restrained letterpress lift: warm espresso-tinted, low spread. The
	   hairline border does the separating; the shadow only whispers. */
	--shadow-dark-source: rgba(46, 33, 26, 0.10);
	--elevation-raised: 0 .1rem .3rem rgba(46, 33, 26, 0.08);
	--elevation-overlay: 0 1.2rem 2.4rem rgba(46, 33, 26, 0.16);
	--elevation-inset: inset 0 .1rem .2rem rgba(46, 33, 26, 0.06);

	--font-display: 'Playfair Display', Georgia, serif;
	--font-body: 'Manrope', 'Inter', system-ui, sans-serif;
	--font-mono: 'Space Mono', ui-monospace, monospace;

	/* Fixed utility greys made themeable (slider/progress tracks). */
}

:root[data-theme="elegant"][data-mode="dark"] {
	--surface-page: #1F1611;
	--surface-card: #2A201A;
	--surface-raised: #322620;
	--surface-sunken: #160F0B;
	--surface-hover: #352A22;
	--surface-selected: #3E3128;
	--surface-overlay: rgba(0, 0, 0, 0.60);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #A8B05E;
	--brand-secondary: #C2A06A;
	--brand-accent: #C2A06A;

	--text-primary: #EDE6D6;
	--text-secondary: #B0A48E;
	/* Espresso ink on the lifted olive/caramel fills — both ≥AA. */
	--text-on-brand: #1F1611;
	--text-on-status: #2E211A;
	--text-disabled: #8C7C69;
	--text-link: #B8BE70;

	--border-default: rgba(237, 230, 214, 0.10);
	--border-strong: rgba(237, 230, 214, 0.20);
	--border-width: .1rem;

	--status-success: #7FB05A;
	--status-warning: #D9A24E;
	--status-danger: #D97A6A;
	--status-partial: #C49A5A;
	--status-info: #8FA39C;

	--focus-ring-color: #A8B05E;

	/* Shapes — same tailored corners as light. */
	--radius-input: .3rem;
	--radius-button: .3rem;
	--radius-card: .6rem;
	--radius-pill: .4rem;
	--radius-sheet: .8rem;

	/* Depth — soft, deep ambient on warm-black; still low-key. */
	--shadow-dark-source: rgba(0, 0, 0, 0.45);
	--elevation-raised: 0 .2rem .6rem rgba(0, 0, 0, 0.45);
	--elevation-overlay: 0 1.2rem 2.4rem rgba(0, 0, 0, 0.55);
	--elevation-inset: inset 0 .1rem .2rem rgba(0, 0, 0, 0.30);

	--font-display: 'Playfair Display', Georgia, serif;
	--font-body: 'Manrope', 'Inter', system-ui, sans-serif;
	--font-mono: 'Space Mono', ui-monospace, monospace;

}

/**
* minimalist.css — minimalist theme role-token overrides (deep theming)
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* The production "minimalist" theme: editorial Swiss minimalism on a Tailwind
* neutral scale. White / soft-gray surfaces, deep-charcoal ink, a SINGLE blue
* accent (#2563EB) reserved for links + primary actions, Inter geometric sans
* throughout. Architectural sharp corners (≤4px), 1px hairline borders, and —
* critically — NO shadows: depth comes entirely from colour blocking + space
* (every elevation token resolves to `none`; the border carries structure).
* The DARK block keeps the discipline on a neutral near-black scale.
*
* Distinct from "modern" (pure greyscale, charcoal/inverted brand): minimalist
* keeps the same restraint but introduces the one blue hue.
*
* text-on-brand is white over the blue brand fill (≥AA). Activated by the
* runtime gate (dt-runtime): `data-theme="minimalist"` on <html>.
*
* @version 2026-Jun-19 Initial deep-theming version (user spec)
* @version 2026-August-10 --surface-brandmark minted for the payments panel card-brand plate — identical in every theme and mode by design
* @version 2026-August-14 --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status minted for ink on the success fill (#1840)
*/

:root[data-theme="minimalist"] {
	--surface-page: #FFFFFF;
	--surface-card: #F3F4F6;
	--surface-raised: #FFFFFF;
	--surface-sunken: #ECEDF0;
	--surface-hover: #ECEDF0;
	--surface-selected: #E3E5EA;
	--surface-overlay: rgba(17, 24, 39, 0.40);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #2563EB;
	--brand-secondary: #4B5563;
	--brand-accent: #2563EB;

	--text-primary: #111827;
	--text-secondary: #4B5563;
	--text-on-brand: #FFFFFF;
	--text-on-status: #111827;
	--text-disabled: #788192;
	--text-link: #2563EB;

	--border-default: #E5E7EB;
	--border-strong: #D1D5DB;
	--border-width: .1rem;

	--status-success: #059669;
	--status-warning: #D97706;
	--status-danger: #DC2626;
	--status-partial: #DB2777;
	--status-info: #2563EB;

	--focus-ring-color: #2563EB;

	--font-display: 'Inter', system-ui, 'Helvetica Neue', sans-serif;
	--font-body: 'Inter', system-ui, 'Helvetica Neue', sans-serif;
	--font-mono: 'Space Mono', ui-monospace, monospace;

	/* Shapes — architectural: sharp, max 4px softening. */
	--radius-input: .4rem;
	--radius-button: .4rem;
	--radius-card: .4rem;
	--radius-pill: .4rem;
	--radius-sheet: .4rem;

	/* Depth — NONE. Colour blocking + the 1px border carry every boundary. */
	--shadow-light-source: transparent;
	--shadow-dark-source: transparent;
	--elevation-flat: none;
	--elevation-button: none;
	--elevation-raised: none;
	--elevation-inset: none;
	--elevation-overlay: none;
	--elevation-glow: none;

}

:root[data-theme="minimalist"][data-mode="dark"] {
	--surface-page: #0B0C0E;
	--surface-card: #15171A;
	--surface-raised: #15171A;
	--surface-sunken: #0F1113;
	--surface-hover: #1B1E22;
	--surface-selected: #23262B;
	--surface-overlay: rgba(0, 0, 0, 0.60);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #2563EB;
	--brand-secondary: #9CA3AF;
	--brand-accent: #2563EB;

	--text-primary: #F3F4F6;
	--text-secondary: #9CA3AF;
	--text-on-brand: #FFFFFF;
	--text-disabled: #657285;
	--text-link: #60A5FA;

	--border-default: rgba(243, 244, 246, 0.12);
	--border-strong: rgba(243, 244, 246, 0.22);
	--border-width: .1rem;

	--status-success: #10B981;
	--status-warning: #F59E0B;
	--status-danger: #EF4444;
	--status-partial: #EC4899;
	--status-info: #60A5FA;

	--focus-ring-color: #2563EB;

	--font-display: 'Inter', system-ui, 'Helvetica Neue', sans-serif;
	--font-body: 'Inter', system-ui, 'Helvetica Neue', sans-serif;
	--font-mono: 'Space Mono', ui-monospace, monospace;

	/* Shapes — same architectural corners as light. */
	--radius-input: .4rem;
	--radius-button: .4rem;
	--radius-card: .4rem;
	--radius-pill: .4rem;
	--radius-sheet: .4rem;

	/* Depth — NONE (same discipline). */
	--shadow-light-source: transparent;
	--shadow-dark-source: transparent;
	--elevation-flat: none;
	--elevation-button: none;
	--elevation-raised: none;
	--elevation-inset: none;
	--elevation-overlay: none;
	--elevation-glow: none;

}

/**
* perspective.css — perspective theme role-token overrides (deep theming)
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* The production "perspective" theme: visionOS frosted glass. Translucent
* white (light) / slate (dark) panels floating over a neutral backdrop, with
* heavy `--surface-blur` backdrop-filter, soft real depth shadows, and large
* rounded (classic, NOT clip-path) corners. One calm blue brand. Manrope sans.
* Graduated from the styleBoard perspective candidate.
*
* The frost is the look: surfaces are translucent + blurred (`--surface-blur`
* on `.tile`), the hairline border defines the panel edge, and the depth comes
* from soft elevation shadows — not opacity alone.
*
* text-on-brand reads over brand-primary == brand-accent (the one blue): white
* on the deep blue (light) / dark ink on the lifted blue (dark) — both ≥AA.
*
* Activated by the runtime gate (dt-runtime): `data-theme="perspective"`
* (+ `data-mode="dark"`) on <html>. See knowledge-base/style/.
*
* @version 2026-Jun-19 Graduated from styleBoard perspective candidate
* @version 2026-August-10 --surface-brandmark minted for the payments panel card-brand plate — identical in every theme and mode by design
* @version 2026-August-14 --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status minted for ink on the success fill (#1840)
*/

:root[data-theme="perspective"] {
	--surface-page: #D9DDE3;
	--surface-card: rgba(255, 255, 255, 0.55);
	--surface-raised: rgba(255, 255, 255, 0.62);
	--surface-sunken: rgba(255, 255, 255, 0.30);
	--surface-hover: rgba(255, 255, 255, 0.35);
	--surface-selected: rgba(255, 255, 255, 0.55);
	--surface-overlay: rgba(20, 24, 35, 0.45);
	--surface-brandmark: #FFFFFF;
	/* Heavy frosted-glass blur — the visionOS signature. */
	--surface-blur: blur(20px);

	--brand-primary: #2F62E6;
	--brand-secondary: #6E9BFF;
	--brand-accent: #2F62E6;

	--text-primary: #1B1D21;
	--text-secondary: #5C606B;
	--text-on-brand: #FFFFFF;
	--text-on-status: #1B1D21;
	--text-disabled: #757B88;
	--text-link: #2F62E6;

	--border-default: rgba(255, 255, 255, 0.45);
	--border-strong: rgba(255, 255, 255, 0.70);
	--border-width: .1rem;

	--status-success: #3FB36A;
	--status-warning: #E0A24E;
	--status-danger: #E5484D;
	--status-partial: #E07AA0;
	--status-info: #2F62E6;

	--focus-ring-color: #2F62E6;

	--font-display: 'Manrope', system-ui, sans-serif;
	--font-body: 'Manrope', system-ui, sans-serif;
	--font-mono: 'Space Mono', ui-monospace, monospace;

	/* Shapes — large rounded (classic) surfaces, no clip-path frame. */
	--radius-input: 1.2rem;
	--radius-button: 1.4rem;
	--radius-card: 2rem;
	--radius-pill: 9999px;
	--radius-sheet: 2.4rem;

	/* Depth — soft real shadows under the floating panels. */
	--elevation-raised: 0 .8rem 3rem rgba(20, 24, 35, 0.18);
	--elevation-overlay: 0 1.4rem 4rem rgba(20, 24, 35, 0.26);

}

:root[data-theme="perspective"][data-mode="dark"] {
	--surface-page: #1C1E24;
	--surface-card: rgba(40, 44, 54, 0.55);
	--surface-raised: rgba(48, 52, 64, 0.62);
	--surface-sunken: rgba(255, 255, 255, 0.05);
	--surface-hover: rgba(255, 255, 255, 0.08);
	--surface-selected: rgba(255, 255, 255, 0.14);
	--surface-overlay: rgba(0, 0, 0, 0.55);
	--surface-brandmark: #FFFFFF;
	--surface-blur: blur(20px);

	--brand-primary: #6E9BFF;
	--brand-secondary: #A9C2FF;
	--brand-accent: #6E9BFF;

	--text-primary: #F0F2F6;
	--text-secondary: #AFB3BD;
	--text-on-brand: #0E1014;
	--text-disabled: #8D929E;
	--text-link: #6E9BFF;

	--border-default: rgba(255, 255, 255, 0.12);
	--border-strong: rgba(255, 255, 255, 0.24);
	--border-width: .1rem;

	--status-success: #4FBE7A;
	--status-warning: #E0A24E;
	--status-danger: #FF6B6F;
	--status-partial: #E07AA0;
	--status-info: #6E9BFF;

	--focus-ring-color: #6E9BFF;

	--font-display: 'Manrope', system-ui, sans-serif;
	--font-body: 'Manrope', system-ui, sans-serif;
	--font-mono: 'Space Mono', ui-monospace, monospace;

	/* Shapes — same rounded surfaces. */
	--radius-input: 1.2rem;
	--radius-button: 1.4rem;
	--radius-card: 2rem;
	--radius-pill: 9999px;
	--radius-sheet: 2.4rem;

	/* Depth — soft real shadows on the dark backdrop. */
	--elevation-raised: 0 .8rem 3rem rgba(0, 0, 0, 0.45);
	--elevation-overlay: 0 1.4rem 4rem rgba(0, 0, 0, 0.55);

}

/**
* power.css — power theme role-token overrides (deep theming)
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* The "power" theme: warm-luxury, dark-first. Deep desaturated-indigo canvas,
* a single warm-orange accent (#E8633A) carrying actions/links/highlights,
* raised cards with rounded corners and soft shadow depth, and full-monospace
* type (IBM Plex Mono, bundled locally; Space Mono fallback). Status hues stay
* distinct (success/warning/danger).
*
* DELIBERATE DEVIATION from the canonical typeui "power" brief
* (https://www.typeui.sh/design-skills/power), which specifies a MONOCHROME
* editorial system — pure-black canvas, white ink, color-as-exception, sharp
* corners, no shadow, Oswald. Product chose the warm-luxury direction shown in
* the reference dashboard (indigo + orange, rounded, soft depth, mono) over the
* literal monochrome brief; this theme intentionally renders that instead. The
* monochrome brief is preserved in git history (initial deep-theming version).
*
* Dark is the real theme (defaultMode dark); light is a warm-luxury sibling —
* cream canvas, white cards, a deeper orange (#B8460F) so white-on-brand stays
* legible. text-on-brand is the ink over the orange fill (near-black on the
* dark-mode orange, white on the deeper light-mode orange).
*
* Activated by the runtime gate: `data-theme="power"` (+ `data-mode="dark"`) on
* <html>. Role tokens only — no value-named tokens (see knowledge-base/style/).
*
* @version 2026-Jun-28 Initial deep-theming version (typeui power brief; monochrome)
* @version 2026-Jun-28 Override to warm-luxury (indigo + orange, rounded, soft
*                      depth, full-mono) per product reference dashboard.
* @version 2026-July-29 Dark --radius-card snapped to the catalog's 0.1rem step
*                       grid (1.25rem → 1.2rem), which also removes an unintended
*                       light/dark asymmetry against the 1.2rem light value.
* @version 2026-August-10 --surface-brandmark minted for the payments panel card-brand plate — identical in every theme and mode by design
* @version 2026-August-14 --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status minted for ink on the success fill (#1840)
*/

:root[data-theme="power"] {
	/* Warm-luxury LIGHT: cream canvas, white cards, deeper-orange accent. */
	--surface-page: #F7F3EC;
	--surface-card: #FFFFFF;
	--surface-raised: #FFFFFF;
	--surface-sunken: #EDE7DC;
	--surface-hover: #F1EADF;
	--surface-selected: #E7DECF;
	--surface-overlay: rgba(40, 28, 16, 0.34);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #C2410C;
	--brand-secondary: #6E665C;
	--brand-accent: #DA5A0A;

	--text-primary: #221E1A;
	--text-secondary: #686057;
	/* White ink over the deeper light-mode orange fill — AA. */
	--text-on-brand: #FFFFFF;
	--text-on-status: #FFFFFF;
	--text-disabled: #867B6F;
	--text-link: #C2410C;

	--border-default: #E6DCCE;
	--border-strong: #D2C6B4;
	--border-width: .1rem;

	--status-success: #15803D;
	--status-warning: #B45309;
	--status-danger: #DC2626;
	--status-partial: #8A8276;
	--status-info: #B8460F;

	--focus-ring-color: #B8460F;

	--font-display: 'IBM Plex Mono', 'Space Mono', 'Courier New', monospace;
	--font-body: 'IBM Plex Mono', 'Space Mono', 'Courier New', monospace;
	--font-mono: 'IBM Plex Mono', 'Space Mono', ui-monospace, monospace;

	/* Shapes — generous, luxurious rounding; full-pill badges. */
	--radius-input: .8rem;
	--radius-button: .8rem;
	--radius-card: 1.2rem;
	--radius-pill: 9999px;
	--radius-sheet: 1.6rem;

	/* Depth — soft, warm elevation. */
	--shadow-light-source: rgba(255, 255, 255, 0.90);
	--shadow-dark-source: rgba(60, 40, 20, 0.18);
	--elevation-flat: none;
	--elevation-button: 0 .1rem .3rem rgba(60, 40, 20, 0.12);
	--elevation-raised: 0 .4rem 1.6rem rgba(60, 40, 20, 0.14);
	--elevation-inset: inset 0 .1rem .3rem rgba(60, 40, 20, 0.10);
	--elevation-overlay: 0 1.6rem 4rem rgba(40, 28, 16, 0.22);
	--elevation-glow: 0 0 1.6rem rgba(184, 70, 15, 0.22);
}

:root[data-theme="power"][data-mode="dark"] {
	/* Warm-luxury DARK — the canonical typeui power skill. Values transcribed
	   from the live computed :root (indigo #262642 surfaces + #ff7a2e orange). */
	--surface-page: #1E1E36;
	--surface-card: #262642;
	--surface-raised: #323256;
	--surface-sunken: #1A1A30;
	--surface-hover: #2A2A48;
	--surface-selected: #323256;
	--surface-overlay: rgba(38, 38, 66, 0.92);
	--surface-brandmark: #FFFFFF;

	--brand-primary: #FF7A2E;
	--brand-secondary: #9496A8;
	--brand-accent: #FF7A2E;

	--text-primary: #F9F6F0;
	--text-secondary: #9D9EAF;
	/* Dark-brown ink over the orange brand fill (typeui brand-medium family). */
	--text-on-brand: #2B1400;
	--text-on-status: #221E1A;
	--text-disabled: #7E7E9E;
	--text-link: #FF7A2E;

	/* typeui borders are white-alpha hairlines. */
	--border-default: rgba(255, 255, 255, 0.12);
	--border-strong: rgba(255, 255, 255, 0.22);
	--border-width: .1rem;

	--status-success: #34D399;
	--status-warning: #FBBF24;
	--status-danger: #F87171;
	--status-partial: #9496A8;
	--status-info: #6366F1;

	--focus-ring-color: #FF7A2E;

	--font-display: 'IBM Plex Mono', 'Space Mono', 'Courier New', monospace;
	--font-body: 'IBM Plex Mono', 'Space Mono', 'Courier New', monospace;
	--font-mono: 'IBM Plex Mono', 'Space Mono', ui-monospace, monospace;

	--radius-input: .8rem;
	--radius-button: .8rem;
	--radius-card: 1.2rem;
	--radius-pill: 9999px;
	--radius-sheet: 1.6rem;

	/* typeui shadow scale (pure-black alpha). */
	--shadow-light-source: transparent;
	--shadow-dark-source: rgba(0, 0, 0, 0.50);
	--elevation-flat: none;
	--elevation-button: 0 .1rem .2rem rgba(0, 0, 0, 0.25);
	--elevation-raised: 0 .8rem 2.4rem rgba(0, 0, 0, 0.32);
	--elevation-inset: inset 0 .1rem .3rem rgba(0, 0, 0, 0.35);
	--elevation-overlay: 0 2.4rem 4.8rem rgba(0, 0, 0, 0.40);
	--elevation-glow: 0 0 1.6rem rgba(255, 122, 46, 0.25);
}

/**
* app.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Token-layer pass: legacy radius/shadow/border aliases bridged
*                       onto role tokens, ROOMY radius + density retune, new type /
*                       density / motion roles, elevation relayer, body type floor.
* @version 2026-July-29 Inter/Poppins repacked as subsetted woff2; font-display: swap on every face
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
* @version 2026-August-04 Shell boxes opt height/width OUT of the global transition: all — dvh resizes at runtime, so the toolbar would drive a 200ms height animation (#1822)
* @version 2026-August-10 --surface-brandmark minted: the card-network mark plate, the one role token that deliberately does not track the theme
* @version 2026-August-14 font-size joins the global transition's exclusion list (the fluid root animated every inherited size on resize); seven unreferenced @keyframes and --_ease-spring deleted
* @version 2026-August-14 Floor --text-secondary / --text-disabled retuned to clear the widened contrast gate; --text-on-status and --text-on-media minted; the commented-out --deadCenter mixin deleted
* @version 2026-August-14 Dark-block comment tombstones removed; the elevation-inversion and --chart-inactive rationale now lives in knowledge-base/style/tokens.md (§ Elevation, § Data-viz) and gotchas/css.md#CSS-15
*/

/* Theme overrides — must precede any other style declarations.
   CSS spec: @import is only honored when it appears before any
   rule blocks (after @charset / @layer only). Putting it lower
   in the file silently invalidates the import. See
   knowledge-base/style/architecture.md for the multi-theme
   pattern. */

/* Single cascade-layer order for the whole bundle. Declaration only — later,
   lower-priority layers win over earlier ones. Wrapping existing rules into
   these layers is a separate bundle-wide pass (out of scope here). See
   knowledge-base/style/architecture.md. */
@layer reset, tokens, base, theme, state, utilities;

html {
	/* Fluid root size (desktop-preserving): 1rem = 8px at ≤320px viewport
	   rising to 10px at ≥800px, so desktops render exactly as the old
	   `font-size: 62.5%` did and only phone/small-tablet widths shrink.
	   Percentages resolve against the browser-initial 16px: 50% = 8px,
	   62.5% = 10px, preferred = 41.667% (6.667px) + 0.4167vw. */
	font-size: clamp(50%, 41.667% + 0.4167vw, 62.5%);
	/* -webkit-print-color-adjust: exact; */
}

body {
	margin: 0;
	font-family: var(--font-body);
	color: var(--text-primary);
	/* Body type floor. `html` is a fluid `clamp(50%, …, 62.5%)` (10px at desktop),
	   so without this every element that never sets its own `font-size` inherits
	   the 10px root — which is why so many components hardcoded a size just to opt
	   out of it. The SIZE floor is 1.4rem (not the roomier 1.6rem), deliberately
	   halving the jump; the LEADING is the retuned 1.5 per the roomy posture.
	   Those are two separate decisions — this comment used to read as if the
	   1.4 applied to both, which cost one integration round to disambiguate.
	   Separately revertible: if the contact sheet shows clipping in fixed-height
	   containers, revert these two lines FIRST. */
	font-size: var(--font-size-body);
	line-height: var(--line-height-body);
	overflow: hidden;
	height: 100dvh;
	width: 100dvw;
	transition: all var(--transition-base), height 0s, width 0s;
}

[contenteditable] {
	user-select: text;
	-moz-user-select: text;
	-webkit-user-select: text;
}

* {
	background-color: transparent;
	margin: 0;
	padding: 0;
	-webkit-box-sizing: border-box;
	-moz-box-sizing: border-box;
	box-sizing: border-box;
	/* Animate everything by default, timed by the themeable --transition-base
	   token. A scoped property list (background-color/color/border/box-shadow/
	   transform) was tried for paint perf, but it left opacity fades, layout,
	   and position changes snapping — too jumpy. Elements with their own
	   transition (e.g. the 3D depth cards) override this, so the broad default
	   doesn't lag their per-frame updates. font-size is excluded (the sanctioned
	   exclusion-list shape, not a property-list narrowing): the fluid `html`
	   clamp moves the rem basis on every resize, so every element inheriting it
	   would animate its computed size for the whole transition duration. */
	transition: all var(--transition-base), font-size 0s;
}

/* Focus-visible ring system (replaces the global `*:focus{outline:none}` kill
   switch). Mouse/pointer focus keeps the prior no-ring behavior; keyboard / AT
   focus gets the themeable ring. outline (not box-shadow) is used: it doesn't
   trigger layout and isn't clipped by overflow:hidden ancestors. WCAG 2.4.11. */
:focus:not(:focus-visible) {
	outline: none;
}

:focus-visible {
	outline: var(--focus-ring-width) solid var(--focus-ring-color);
	outline-offset: var(--focus-ring-offset);
	border-radius: inherit;
}

/* Honor user motion preference: neutralize transitions + animations app-wide.
   Covers the loading shimmer and the scoped transition above. WCAG 2.3.3. */
@media (prefers-reduced-motion: reduce) {

	*,
	*::before,
	*::after {
		animation-duration: .001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .001ms !important;
		scroll-behavior: auto !important;
	}
}

:root {
	/* ============================================================
	   There is ONE token vocabulary: the role tokens. The legacy
	   `Capitalized_Snake` / `snake_case` aliases are retired, and
	   `retiredTokens.test.js` fails the build on any reintroduction —
	   necessary because a missing custom property fails SILENTLY: it is
	   invalid at computed-value time, so the property falls back to
	   inherited/initial and a colour just quietly goes transparent.

	   DELIBERATELY KEPT below, and this is the COMPLETE list: the `--Badge_*`
	   family (a real semantic layer — "retint badges without touching the
	   base palette" — and read from `baseElements.js`, so its legacy-style
	   naming is a separate consistency question, not debt), plus four
	   literal-valued app tokens: `--app-Blue`, `--app-Gray-mid`,
	   `--text-shadow-hover` and `--border-shorthand`. Every other legacy
	   token was removed outright with its consumers rewritten; there is no
	   deferred phase.

	   Why the retirement was safe, and why it beat a lint rule:
	   knowledge-base/style/tokens.md#legacy-aliases--retired
	   ============================================================ */
	/* Custom Colors */
	--app-Blue: rgb(119, 167, 244);
	--app-Gray-mid: rgb(166, 166, 166);
	/* Badge colors — the palette `getBadge` draws from (see BADGE_BACKGROUNDS in
	   baseElements.js). Each derives from a themeable role token via var(), so
	   badges re-theme with the active theme / per-entity customization; override
	   just these to retint badges without touching the base palette. That
	   independent-retint seam is why this family SURVIVED the retirement above —
	   it is a semantic layer, not an alias. */
	--Badge_Neutral_Background: transparent;
	--Badge_Highlight_Background: var(--brand-accent);
	--Badge_Success_Background: var(--status-success);
	--Badge_Warning_Background: var(--status-warning);
	--Badge_Partial_Background: var(--status-partial);
	--Badge_Danger_Background: var(--status-danger);
	/* Text drawn on top of a filled badge vs. the outline-only neutral badge. */
	--Badge_On_Fill_Font_Color: var(--text-on-brand);
	--Badge_Neutral_Font_Color: var(--text-primary);
	/* intentional literal: text-shadow has no --elevation-* role to bridge onto */
	--text-shadow-hover: .15rem .15rem rgba(0, 0, 0, 0.075);
	/* Composite shorthand, not an alias — expanding it at its 36 call sites
	   would be strictly worse than keeping it, so it was RENAMED into the role
	   vocabulary (from `--default_border`) rather than retired. */
	--border-shorthand: var(--border-width) solid var(--border-default);

	/* ============================================================
	   DEEP-THEMING TOKEN SYSTEM (Phase 1, deep-theming plan).
	   Two tiers: `--_`-prefixed PRIMITIVES (fixed cascade floor,
	   never themed) and bare-kebab semantic ROLE tokens (themeable;
	   the CUSTOMIZABLE_STYLES candidate set). Role tokens alias into
	   primitives. Added additively — modern-light defaults mirror
	   today's values; legacy tokens above stay live until the rename
	   codemod (plan step 1.6). Signal: bare role = themeable; `--_` =
	   fixed. See knowledge-base/style/architecture.md (rewrite pending).
	   ============================================================ */

	/* --- PRIMITIVE FLOOR (--_, cascade-only) --- */
	--_grey-50: #fafafc;
	--_grey-100: #f1efef;
	--_grey-200: #e6e6e6;
	--_grey-300: #d9d9de;
	--_grey-400: #a6a6a6;
	--_grey-500: #8c8c8c;
	--_grey-600: #646464;
	--_grey-700: #3f4a5f;
	--_radius-none: 0;
	--_radius-sm: .5rem;
	--_radius-md: 1rem;
	--_radius-lg: 1.6rem;
	/* xl retuned 2.5rem → 2rem to give --radius-sheet a 20px rung; the old 2.5rem
	   is preserved as 2xl behind the new --radius-shell, so nothing is retired.
	   Free: --_radius-* has zero consumers outside this block and no theme file
	   re-declares a primitive. */
	--_radius-xl: 2rem;
	--_radius-2xl: 2.5rem;
	--_radius-full: 9999px;
	--_space-0: 0;
	--_space-05: .2rem;
	--_space-1: .4rem;
	--_space-2: .8rem;
	--_space-3: 1.2rem;
	--_space-4: 1.6rem;
	--_space-5: 2.4rem;
	--_space-6: 3.2rem;
	--_space-7: 4.8rem;
	/* Type ladder 10/12/14/16/20/24/30/36px. 2xs is new (the .7–.85rem cluster's
	   legibility floor); the top two rungs were pulled down so no gap above 12px
	   exceeds 25% — that is what lets every codemod collapse honour the drift cap. */
	--_text-2xs: 1rem;
	--_text-xs: 1.2rem;
	--_text-sm: 1.4rem;
	--_text-md: 1.6rem;
	--_text-lg: 2rem;
	--_text-xl: 2.4rem;
	--_text-2xl: 3rem;
	--_text-3xl: 3.6rem;
	/* Shadow casters. A layered shadow needs a tight contact layer plus a diffuse
	   ambient one; the cool tint (slate rather than pure black) is what keeps a
	   shadow from reading muddy over a tinted surface. */
	--_shadow-contact: rgba(15, 23, 42, .06);
	--_shadow-ambient: rgba(15, 23, 42, .10);
	--_shadow-key: rgba(15, 23, 42, .16);
	--_ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
	--_ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
	/* A true ease-out. --_ease-standard has an ease-IN front half and is wrong for
	   entrances (see --ease-enter). */
	--_ease-decelerate: cubic-bezier(0, 0, 0.2, 1);

	/* --- SEMANTIC ROLE TOKENS (themeable; modern-light defaults) --- */
	/* surfaces */
	--surface-page: rgb(250, 250, 250);
	--surface-card: #ffffff;
	--surface-raised: #ffffff;
	--surface-sunken: #f1eff6;
	--surface-hover: #F0E8FA;
	--surface-selected: #EADCFB;
	--surface-overlay: rgba(0, 0, 0, .3);
	/* The plate a third-party card-network mark sits on. The ONE role token that
	   deliberately does NOT track the theme: every theme declares it, and every
	   theme declares it light, because Visa's mark is blue-on-white, Amex's is
	   white-on-blue and Mastercard's circles assume a light ground — all three
	   forbid recolouring, and --surface-raised is near-black on three themes and
	   in every dark mode. Not in the StyleProperties catalog: a customer
	   recolouring a Visa plate is a trademark problem, not a preference.
	   See knowledge-base/style/tokens.md. */
	--surface-brandmark: #FFFFFF;
	/* brand */
	--brand-primary: #9D33F2;
	--brand-secondary: #7C3AED;
	--brand-accent: #EE4368;
	/* text */
	--text-primary: #3f4a5f;
	--text-secondary: #606273;
	--text-on-brand: #ffffff;
	--text-on-status: #0F0F12;
	--text-disabled: #7E7E7E;
	--text-link: #9D33F2;
	/* Ink drawn over uncontrolled imagery (photos, video). Deliberately fixed
	   white in every theme and both modes, like --surface-brandmark.
	   See knowledge-base/style/tokens.md. */
	--text-on-media: #FFFFFF;
	/* border */
	--border-default: rgba(0, 0, 0, .1);
	--border-strong: rgba(0, 0, 0, .2);
	--border-width: .1rem;
	/* status */
	--status-success: #85BB65;
	--status-warning: #F2A65A;
	--status-danger: #EE4368;
	--status-partial: #F19BB3;
	--status-info: #297aef;
	/* focus ring (a11y, themeable; width never < 2px per WCAG 2.4.11) */
	--focus-ring-color: #297aef;
	--focus-ring-width: .2rem;
	--focus-ring-offset: .2rem;
	/* typography */
	--font-display: 'Poppins', system-ui, sans-serif;
	--font-body: 'Poppins', 'inter', helvetica, sans-serif;
	--font-mono: ui-monospace, 'Courier New', monospace;
	/* One role per ladder rung, so no component ever needs to reach for a --_
	   primitive. Names are functional, never value-named. */
	--font-size-label: var(--_text-2xs);
	--font-size-caption: var(--_text-xs);
	--font-size-body: var(--_text-sm);
	--font-size-lead: var(--_text-md);
	--font-size-subheading: var(--_text-lg);
	--font-size-heading: var(--_text-xl);
	--font-size-stat: var(--_text-2xl);
	--font-size-display: var(--_text-3xl);
	--font-weight-body: 400;
	--font-weight-medium: 500;
	--font-weight-heading: 600;
	--font-weight-display: 700;
	--line-height-tight: 1.2;
	--line-height-body: 1.5;
	--line-height-relaxed: 1.65;
	/* shape — radius roles. ROOMY posture: inputs/buttons 10px, cards 16px,
	   sheets 20px, outermost shells 25px — the targets knowledge-base/style/
	   modern.md already documents, which the shipped 5px/10px undershot.
	   --radius-dense is the mandatory dense-data-surface exception. */
	--radius-dense: var(--_radius-sm);
	--radius-input: var(--_radius-md);
	--radius-button: var(--_radius-md);
	--radius-card: var(--_radius-lg);
	--radius-sheet: var(--_radius-xl);
	--radius-shell: var(--_radius-2xl);
	--radius-pill: var(--_radius-full);
	--radius-avatar: var(--_radius-full);
	/* 50% remains distinct from a pill: on a non-square box it preserves an
	   ellipse rather than turning it into a stadium. */
	--radius-circle: 50%;
	/* elevation — full box-shadow value strings + themeable casters */
	--shadow-light-source: transparent;
	--shadow-dark-source: var(--_shadow-ambient);
	/* The dark-mode top highlight, exposed as a role so a theme can kill it
	   rather than fight a hardcoded rgba(255,255,255,…). Floor is transparent. */
	--border-highlight: transparent;
	/* Glassmorphism backdrop-filter — themes opt in (e.g. modern/cyber glass);
	   floor is `none` so opaque themes pay no blur cost. Consumed by `.tile`. */
	--surface-blur: none;
	/* Selection/focus paint is an alpha overlay, not --surface-selected: themes
	   may make the latter opaque for selected rows. */
	--state-selection-highlight: color-mix(in srgb, var(--brand-accent) 25%, transparent);
	/* Relayered: y-only offsets (an equal x/y offset is the dated "light from the
	   upper-left" tell) and a tight contact layer under a diffuse ambient one.
	   These are the FLOOR — 7 of 10 themes override raised/overlay in their own
	   file, so never swap a call site by matching a literal against these strings;
	   swap by role. */
	--elevation-flat: none;
	--elevation-button: 0 .1rem .2rem var(--_shadow-contact);
	--elevation-raised: 0 .1rem .2rem var(--_shadow-contact), 0 .4rem 1.2rem -.2rem var(--shadow-dark-source);
	--elevation-inset: inset 0 .1rem .2rem var(--_shadow-contact);
	--elevation-overlay: 0 .2rem .4rem var(--_shadow-contact), 0 1.6rem 3.2rem -.8rem var(--_shadow-key);
	--elevation-glow: 0 0 1.6rem -.2rem var(--brand-accent);
	/* The one OMNIDIRECTIONAL rung — no y-offset, so it reads as a ring around the
	   element rather than a drop beneath it. Exists because the legacy
	   --box-shadow-hover-far it backs is applied to round / knob surfaces (the
	   slider knob, the avatar in entityImageAndName, the notePad corner) where a
	   directional drop looks wrong; its pre-bridge literal was likewise offsetless
	   (`0 0 .8rem .1rem rgba(0,0,0,.3)`), so "far" always meant "spreads outward",
	   never "farther away". Keeps the .1rem spread that made it read as a ring.
	   Named for what it does (surrounds the box evenly) — NOT "halo", which means a
	   ring of LIGHT and is already what --elevation-glow above is for; this one is a
	   ring of shadow. Composed from the themeable --shadow-dark-source caster (5
	   themes retint it); the other themes fall through to the --_shadow-ambient
	   floor. NOT in the StyleProperties catalog — same as --elevation-flat /
	   --elevation-button; a theme wanting a different one overrides this role. */
	--elevation-surround: 0 0 .4rem var(--_shadow-contact), 0 0 1.2rem .1rem var(--shadow-dark-source);
	--surface-clip: none;
	/* data-viz — chart gradient (themeable; floor reuses the legacy purple).
	   The legacy --Chart_Gradient alias that used to front this was retired; chart
	   consumers now read this role token directly. */
	--chart-gradient: linear-gradient(135deg, #7C3AED 0%, #9D33F2 35%, #D946EF 70%, #EE4368 100%);
	/* data-viz CATEGORICAL — the ordered set a segmented/categorical chart draws
	   from. Minted because TaskStatusBreakdown was pulling its three segments from
	   three UNRELATED role families (brand / badge / a legacy literal), so no theme
	   could restyle the chart coherently and one segment was theme-blind. Chart
	   consumers now read this one namespace.

	   `active` and `complete` deliberately alias the brand/status roles rather than
	   holding their own hex: that preserves today's rendering exactly AND keeps a
	   theme's accent change flowing through to the chart. `inactive` needs its own
	   value — it is the one that must NOT track a text or brand role.

	   Contrast-verified against BOTH card surfaces (WCAG 1.4.11 wants >= 3:1 for
	   non-text graphical objects): inactive is 4.83:1 on #ffffff and 6.76:1 on the
	   dark #1B1B20. The three are separated by HUE (magenta / green / slate), not by
	   luminance — adjacent-slice luminance ratios are 1.1-2.1:1, so a chart that
	   relies on lightness alone to separate series needs a legend or labels. */
	--chart-active: var(--brand-accent);
	--chart-complete: var(--status-success);
	--chart-inactive: #6B7280;
	/* density / spacing roles — one role per job, ordered tight → roomy, so no
	   component ever needs a --_space-* primitive. The *-inline pair exists
	   because axis-asymmetric control padding cannot be expressed as one scalar
	   (and a two-value shorthand would be mangled by the customize panel's
	   single-number length probe).
	   Canonical control composition:
	     padding: var(--pad-input) var(--pad-input-inline);
	     padding: var(--pad-button) var(--pad-button-inline);
	   --pad-cell / --gap-tight / --pad-row / --pad-shell exist because real dense
	   surfaces sit at 4–5px and real shells at 32px: a blanket 8px floor would
	   have EXPANDED the permission matrix and task rows. */
	--pad-cell: var(--_space-1);
	--pad-dense: var(--_space-2);
	--pad-row: var(--_space-3);
	--pad-input: var(--_space-3);
	--pad-input-inline: var(--_space-4);
	--pad-button: var(--_space-3);
	--pad-button-inline: var(--_space-5);
	--pad-card: var(--_space-4);
	--pad-sheet: var(--_space-5);
	--pad-page: var(--_space-5);
	--pad-shell: var(--_space-6);
	--gap-hairline: var(--_space-05);
	--gap-tight: var(--_space-1);
	--gap-dense: var(--_space-2);
	--gap-inline: var(--_space-2);
	--gap-stack: var(--_space-3);
	--gap-tile: var(--_space-4);
	--gap-section: var(--_space-5);
	--touch-target-primary: 44px;
	/* motion */
	--motion-fast: 200ms;
	--motion-base: 350ms;
	--motion-slow: 500ms;
	/* The ~4px entrance translate, tokenized so it is tunable in one place rather
	   than repeated at every entrance site. Pairs with --motion-base + --ease-enter. */
	--motion-enter-distance: .4rem;
	--ease-standard: var(--_ease-standard);
	--ease-emphasized: var(--_ease-emphasized);
	/* Entrances only — never ease-in. */
	--ease-enter: var(--_ease-decelerate);
	--transition-base: var(--motion-base) var(--ease-standard);
	/* scrollbar — themeable role tokens; consumed by the scrollbar block below. */
	--scrollbar-thumb: var(--brand-accent);
	--scrollbar-thumb-hover: var(--brand-primary);
	--scrollbar-track: transparent;
}

/* Phone-band density step-down. 24px of page gutter per side costs ~12% of a
   320px viewport (the fluid root makes 1rem = 8px there, so --pad-page is 19px
   a side), which is a lot of screen to spend on nothing. One step down the
   ladder, once, in the floor — every view that reads --pad-page inherits it.
   Gated on the `data-viewport` attribute and NEVER on a width media query, per
   ratified decision 0004 (knowledge-base/decisions/0004-viewport-band-axis.md).

   This is a DEFAULT, not a floor — per-entity customization erases it. `pad-page`
   is an editable knob (`customizableStyles.js`), and `setStyle` writes role tokens
   as an INLINE style on `<html>`, which outranks every selector including this one.
   So an entity that customizes page padding keeps its chosen value at phone width
   too. That is the intended precedence (an explicit user choice beats a built-in
   default), but it does mean you cannot rely on this rule to bound the gutter on a
   customized entity — don't chase it as a cascade bug. */
:root[data-viewport="phone"] {
	--pad-page: var(--_space-4);
}

/*  */
[data-slot] {
	display: contents;
}

/* Scrollbar styling — 0.6rem (6px) width across all browsers, matching Firefox's
   native `scrollbar-width: auto` on Linux (measured against FF 148, 2026-Jul-15).
   Chromium + WebKit sized via `::-webkit-scrollbar`; Firefox uses its native width
   and only needs `scrollbar-color` for theming (scoped Firefox-only below).
   The standard `scrollbar-width` / `scrollbar-color` properties are NOT set on
   Chromium because (a) Chrome 121+ ignores `::-webkit-scrollbar-*` on any element
   where a standard scrollbar prop is non-initial, and (b) `scrollbar-color`
   inherits, so setting it on html would silently disable the webkit pseudos
   app-wide. Themes / dark mode adapt via the :root role tokens. */

*::-webkit-scrollbar {
	width: 0.6rem;
	height: 0.6rem;
}

*::-webkit-scrollbar-track {
	background: var(--scrollbar-track);
}

*::-webkit-scrollbar-thumb {
	background: color-mix(in srgb, var(--scrollbar-thumb) 42.5%, transparent);
	border-radius: 0.6rem;
}

*::-webkit-scrollbar-thumb:hover {
	background: var(--scrollbar-thumb-hover);
}

*::-webkit-scrollbar-corner {
	background: transparent;
}

/* Firefox theming — scoped via `@supports selector(::-moz-list-bullet)`, a
   Firefox-only pseudo, so Chromium never parses these declarations. */
@supports selector(::-moz-list-bullet) {
	html {
		scrollbar-width: auto;
		scrollbar-color: color-mix(in srgb, var(--scrollbar-thumb) 42.5%, transparent) var(--scrollbar-track);
	}
}

/* Cross-theme dark role-token overrides. */
:root[data-mode="dark"] {
	--surface-page: #0F0F12;
	--surface-card: #1B1B20;
	--surface-raised: #22222A;
	--surface-sunken: #141418;
	--surface-hover: #26262C;
	--surface-selected: #2E2E36;
	--surface-overlay: rgba(0, 0, 0, .5);
	--text-primary: #ffffff;
	--text-secondary: #9999A0;
	--text-on-brand: #ffffff;
	--text-disabled: #7A7A7A;
	--border-default: rgba(255, 255, 255, .08);
	--border-strong: rgba(255, 255, 255, .16);
	--border-highlight: rgba(255, 255, 255, .06);
	--focus-ring-color: #6E9BFF;
	--shadow-dark-source: rgba(0, 0, 0, .5);
	--elevation-button: inset 0 .1rem 0 var(--border-highlight), 0 .1rem .2rem rgba(0, 0, 0, .45);
	--elevation-raised: inset 0 .1rem 0 var(--border-highlight), 0 .2rem .4rem rgba(0, 0, 0, .45), 0 .8rem 2.4rem -.4rem var(--shadow-dark-source);
	--elevation-inset: inset 0 .1rem .2rem rgba(0, 0, 0, .45);
	--elevation-overlay: inset 0 .1rem 0 rgba(255, 255, 255, .08), 0 .4rem .8rem rgba(0, 0, 0, .5), 0 2.4rem 4.8rem -1.2rem rgba(0, 0, 0, .7);
	--elevation-glow: 0 0 2rem -.2rem var(--brand-accent);
	--elevation-surround: 0 0 .4rem rgba(0, 0, 0, .45), 0 0 1.6rem .1rem var(--shadow-dark-source);
	--chart-inactive: #9CA3AF;
}

#root {
	width: 100dvw;
	height: 100dvh;
	transition: all var(--transition-base), height 0s, width 0s;
}

@media print {
	* {
		break-after: auto;
		break-before: auto;
		break-inside: avoid;
		/* break-inside: page; */
		/* break-before: page;
         break-inside: page; */
		/* break-before: always;
        -webkit-region-break-inside: avoid; */
	}
}

/* Custom fonts

   Two registration paths exist and both must be kept in step:
   (a) the static @font-face blocks below — faces every document needs
       regardless of theme (the pre-theme floor, plus Inter and IBM Plex Mono);
   (b) the per-theme FontFace manifest at utilities/themes/themes.js
       (`fonts.assets[]`), registered by `ensureThemeFontsLoaded` during
       `setStyle` — theme-identity faces, fetched only for the applied theme.
   Adding a face to only one of the two is the classic "theme declares a family
   it never loads" bug. See knowledge-base/style/typography.md.

   Every block declares `font-display: swap`: the CSS default (`auto`) gives a
   block period of up to 3s, i.e. invisible text on first paint. */

/* Decorative faces — NO live CSS consumer today (the commented-out alternate
   body-font lines that used to reference them went out with the legacy alias
   retirement; the only other mentions are email inline styles where
   @font-face never applies). @font-face is lazy, so they cost no runtime bytes;
   retained because a per-entity `Body Font` customization is free-text CSS and
   could in principle name one. */
@font-face {
	font-family: 'Coda-Regular';
	src: url('./assets/fonts/Coda-Regular.ttf') format('truetype');
	font-display: swap;
}

@font-face {
	font-family: 'Coda-Heavy';
	src: url('./assets/fonts/Coda-Heavy.ttf') format('truetype');
	font-display: swap;
}

@font-face {
	font-family: 'Atomic-Age';
	src: url('./assets/fonts/atomicage-regular-webfont.woff') format('woff');
	font-display: swap;
}

@font-face {
	font-family: 'Acumin-Bold';
	src: url('./assets/fonts/Acumin-BdPro.otf') format('opentype');
	font-display: swap;
}

@font-face {
	font-family: 'Acumin';
	src: url('./assets/fonts/Acumin-RPro.otf') format('opentype');
	font-display: swap;
}

@font-face {
	font-family: 'Apex-Normal';
	src: url('./assets/fonts/ACPEX-NORMAL.ttf') format('truetype');
	font-display: swap;
}

@font-face {
	font-family: 'Kusangi';
	src: url('./assets/fonts/Kusanagi.otf') format('opentype');
	font-display: swap;
}

@font-face {
	font-family: 'Oxta';
	src: url('./assets/fonts/Oxta.ttf') format('truetype');
	font-display: swap;
}

@font-face {
	font-family: 'Squarix';
	src: url('./assets/fonts/SQUARIX.ttf') format('truetype');
	font-display: swap;
}

/* Inter (OFL) — variable weight axis 100-900, split latin / latin-ext by
   unicode-range so a boot that never renders an extended glyph downloads
   48 KB instead of the whole family. Sourced from @fontsource-variable/inter
   5.3.0 (upstream Inter v4.1). Verified by binary FeatureList probe: these
   subsets retain `tnum` (tabular figures); Google's subsetting drops Inter's
   `zero`/`cv01`, neither of which has a consumer here.
   `format('woff2')`, not fontsource's legacy `format('woff2-variations')` —
   the latter is only understood by browsers we no longer target. */
@font-face {
	font-family: 'Inter';
	src: url('./assets/fonts/inter/Inter-latin.woff2') format('woff2');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Inter';
	src: url('./assets/fonts/inter/Inter-latin-ext.woff2') format('woff2');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: 'Inter';
	src: url('./assets/fonts/inter/Inter-latin-italic.woff2') format('woff2');
	font-weight: 100 900;
	font-style: italic;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Inter';
	src: url('./assets/fonts/inter/Inter-latin-ext-italic.woff2') format('woff2');
	font-weight: 100 900;
	font-style: italic;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Poppins (OFL) — the pre-theme --font-body/--font-display floor: the face the
   brief pre-setStyle paint uses. All 10 themes override both tokens, so this is
   the only surface it still reaches. Sourced from @fontsource/poppins 5.3.0; the
   1.29 MB of .ttf it replaces carried Devanagari shaping tables the Latin
   subsets correctly drop. Weights 400/500/600/700 only — no --font-weight-*
   token or CSS rule selects 800/900. */
@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-400.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-500.woff2') format('woff2');
	font-weight: 500;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-600.woff2') format('woff2');
	font-weight: 600;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-700.woff2') format('woff2');
	font-weight: 700;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-400-italic.woff2') format('woff2');
	font-weight: 400;
	font-style: italic;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-700-italic.woff2') format('woff2');
	font-weight: 700;
	font-style: italic;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-ext-400.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-ext-500.woff2') format('woff2');
	font-weight: 500;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-ext-600.woff2') format('woff2');
	font-weight: 600;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-ext-700.woff2') format('woff2');
	font-weight: 700;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-ext-400-italic.woff2') format('woff2');
	font-weight: 400;
	font-style: italic;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: 'Poppins';
	src: url('./assets/fonts/Poppins-latin-ext-700-italic.woff2') format('woff2');
	font-weight: 700;
	font-style: italic;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* IBM Plex Mono (OFL) — bundled locally for the power theme's full-mono type.
   Latin subset; weights 400/500/600/700. */
@font-face {
	font-family: 'IBM Plex Mono';
	src: url('./assets/fonts/IBMPlexMono-Regular.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'IBM Plex Mono';
	src: url('./assets/fonts/IBMPlexMono-Medium.woff2') format('woff2');
	font-weight: 500;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'IBM Plex Mono';
	src: url('./assets/fonts/IBMPlexMono-SemiBold.woff2') format('woff2');
	font-weight: 600;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'IBM Plex Mono';
	src: url('./assets/fonts/IBMPlexMono-Bold.woff2') format('woff2');
	font-weight: 700;
	font-style: normal;
	font-display: swap;
}

/* Standard `transform` only. The prior form declared `-webkit-transform` alone
   (unprefixed since 2013/2016, so every step was ignored by spec-compliant
   parsing) and wrote `translateX(-10)` / `translateX(10)` — a unitless non-zero
   length is invalid CSS, so those four steps were silently dropped and the cue
   only jittered at 75%/92%. Restoring them makes the shake read at its authored
   amplitude. The two prefixed duplicate blocks that followed are deleted. */
@keyframes shake {

	8%,
	41% {
		transform: translateX(-1rem);
	}

	25%,
	58% {
		transform: translateX(1rem);
	}

	75% {
		transform: translateX(-.5rem);
	}

	92% {
		transform: translateX(.5rem);
	}

	0%,
	100% {
		transform: translateX(0);
	}
}

@keyframes wander {

	0%,
	10% {
		transform: translate(.1rem, .1rem);
	}

	25% {
		transform: translate(.2rem, .2rem);
	}

	50% {
		transform: translate(.3rem, .1rem);
	}

	75% {
		transform: translate(.2rem, .0rem);
	}

	100% {
		transform: translate(.1rem, .1rem);
	}
}

/**
* depth.css — app-wide [data-depth="3d"] gate for the ambient WebGL layer + card depth
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* Everything here is scoped under html[data-depth="3d"], written by
* Application.setStyle from the per-device depth preference (isDepth3d()).
* 2D sessions never match a single rule below — strictly additive.
*
* @version 2026-Jun-19 Initial Version (incorporation of the styleBoard 3D experiment)
* @version 2026-August-14 Card depth resolves --elevation-raised/--elevation-overlay; the bespoke casters were light-only and vanished in dark mode (#1840)
*/

/* The Ambient3D canvas self-mounts to <body> with an inline z-index:0. In the
   app we push it BEHIND the content (negative z) and make the app's opaque
   background transparent so the room shows through. Ambient3D sets
   scene.background = --surface-page, so the page colour is preserved as the
   backdrop — only now it's a lit 3D room rather than a flat fill. */
html[data-depth="3d"] .ambient3d__canvas {
	z-index: -1 !important;
}

/* Only reveal the room when it actually mounts (WebGL present + 3D picked).
   AmbientBackground adds the canvas; if WebGL is absent the canvas never
   appears, so keep the app background opaque to avoid a bare white page. */
html[data-depth="3d"] body:has(.ambient3d__canvas) .application__view {
	background: transparent;
}

/* Establish a shared 3D context so card lifts read with perspective. */
html[data-depth="3d"] .application__view {
	perspective: 1600px;
}

/* ── Card depth ────────────────────────────────────────────────────────────
   Every card primitive (.pillBox) lifts off the page with a soft shadow when
   3D is on, and floats higher on hover. Needs no GPU — this is the visible
   2D↔3D difference on every screen. The cursor-tracking tilt + pinned-light
   directional shadow from the styleBoard sandbox are a follow-up (they need an
   app-root pointer driver + per-card hit-testing). */
html[data-depth="3d"] .pillBox {
	box-shadow: var(--elevation-raised);
	transition: transform var(--motion-base) var(--ease-standard), box-shadow var(--motion-base) var(--ease-enter);
}

html[data-depth="3d"] .pillBox:hover {
	transform: translateY(-.4rem);
	box-shadow: var(--elevation-overlay);
}

/* Opt-in extra-depth hook for non-pillBox containers. */
html[data-depth="3d"] .depthCard {
	box-shadow: var(--elevation-raised);
	transition: transform var(--motion-base) var(--ease-standard), box-shadow var(--motion-base) var(--ease-enter);
}

/**
 * baseElements.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2019-09-24 Initial Version
 * @version 2026-July-03 .visuallyHidden utility + fieldset/legend UA reset (#731)
 * @version 2026-July-29 Spacing / radius / type literals collapsed onto the app.css
 *   role-token ladder. Retained literals carry an inline `intentional literal` note.
 * @version 2026-July-29 .emptyState / .emptyState-withAction / .emptyState__icon / .emptyState__action styles for getEmptyState (#1764).
 * @version 2026-August-10 .toggle — the controlled two-state switch (track/knob, third pending state, phone touch floor)
 * @version 2026-August-14 Phone-band .form-label one rung up — the required-fields note read 8.29px at 390px
 * @version 2026-August-14 .tooltip / .tooltiptext deleted with getTooltip (zero callers)
 */

/* #region toggle — the controlled switch (getToggle) */

.toggle {
	display: inline-flex;
	align-items: center;
	position: relative;
	/* intentional literal: fixed control dimensions, not spacing rhythm */
	width: 4.4rem;
	height: 2.4rem;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
}

.toggle[disabled] {
	cursor: default;
}

.toggle__track {
	position: absolute;
	inset: 0;
	border-radius: var(--radius-pill);
	background: var(--surface-sunken);
}

.toggle__knob {
	position: absolute;
	/* intentional literal: fixed control dimensions, not spacing rhythm */
	width: 1.8rem;
	height: 1.8rem;
	left: .3rem;
	border-radius: var(--radius-circle);
	background: var(--surface-raised);
	box-shadow: var(--elevation-surround);
}

.toggle[data-toggle-state="on"] .toggle__track {
	background: var(--brand-accent);
}

.toggle[data-toggle-state="on"] .toggle__knob {
	transform: translateX(2rem);
}

.toggle[data-toggle-state="pending"] .toggle__track {
	background: var(--status-warning);
}

.toggle[data-toggle-state="pending"] .toggle__knob {
	transform: translateX(1rem);
}

.toggle[disabled] .toggle__track {
	background: var(--text-disabled);
}

.toggle-large {
	/* intentional literal: fixed control dimensions, not spacing rhythm */
	width: 5.6rem;
	height: 3rem;
}

.toggle-large .toggle__knob {
	/* intentional literal: fixed control dimensions, not spacing rhythm */
	width: 2.4rem;
	height: 2.4rem;
}

.toggle-large[data-toggle-state="on"] .toggle__knob {
	transform: translateX(2.6rem);
}

.toggle-large[data-toggle-state="pending"] .toggle__knob {
	transform: translateX(1.3rem);
}

:root[data-viewport="phone"] .toggle {
	min-height: var(--touch-target-primary);
	min-width: var(--touch-target-primary);
}

/* #endregion toggle */

.elementContainer {
	width: auto;
	height: auto;
}

/* Visually removed but still announced by assistive tech (the standard
   clip-pattern). For content whose VISUAL design already communicates what AT
   needs told explicitly: hidden legends, the app live region, etc. Never use
   display:none / visibility:hidden for that — those hide from AT too. */
.visuallyHidden {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	/* intentional literal: fixed a11y clip-pattern hairline, not spacing rhythm */
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* getFieldset/getLegend (#731): strip the UA fieldset chrome so semantic
   grouping is layout-free — a fieldset drops into any existing grid/flex
   without visual change. min-inline-size unsets the UA min-content quirk
   that otherwise blocks fieldsets from shrinking inside grids. */
.fieldset {
	border: none;
	padding: 0;
	margin: 0;
	min-inline-size: 0;
}

.legend {
	padding: 0;
}

.elementContainer-rounded {
	border-radius: var(--radius-card);
}

.elementContainer-imgBackground {
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

.elementContainer-leftBorder {
	border-left: var(--border-width) solid var(--border-default);
}

.elementContainer-topBorder {
	border-top: var(--border-width) solid var(--border-default);
}

.elementContainer-bottomBorder {
	border-bottom: var(--border-width) solid var(--border-default);
}

.elementContainer-rightBorder {
	border-right: var(--border-width) solid var(--border-default);
}

.elementContainer-allBorder {
	border: var(--border-width) solid var(--border-default);
}

.tileContainer {
	padding: var(--pad-card);
	border-radius: var(--radius-card);
	background-color: var(--surface-card);
	border-color: var(--border-default);
}

.tileContainer-hover {
	cursor: pointer;
}

.tileContainer-hover:hover {
	box-shadow: var(--elevation-raised);
	transform: scale(1.01);
}

.button {
	width: fit-content;
	height: fit-content;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: none;
	border-radius: var(--radius-button);
	cursor: pointer;
	font-family: var(--font-body);
	color: var(--text-primary);
	box-shadow: var(--elevation-button);
	padding: var(--pad-cell) var(--pad-button);
	gap: var(--gap-tight);
}

.button:disabled {
	color: var(--text-disabled);
	background-color: transparent;
	border-color: var(--border-default);
	box-shadow: var(--elevation-flat);
	pointer-events: none;
}

.button:active {
	box-shadow: var(--elevation-inset);
	text-shadow: none;
}

.button-lightBackground,
.button-darkBackground {
	border: var(--border-width) solid var(--border-default);
}

.button-darkBackground,
.button-lightBackground:hover,
.button-lightBackground:focus-visible:not(.button-loading) {
	background-color: var(--brand-accent);
	color: var(--text-on-brand);
	border-color: var(--brand-accent);
}

.button-darkBackground:hover,
.button-darkBackground:focus-visible:not(.button-loading) {
	background-color: transparent;
	color: var(--text-primary);
	border-color: var(--border-default);
}

.button-danger {
	border: var(--border-width) solid var(--status-danger);
	background-color: var(--status-danger);
	color: var(--text-on-brand);
}

.button-danger:hover,
.button-danger:focus-visible:not(.button-loading) {
	background-color: transparent;
	color: var(--status-danger);
}

/* .button-darkBackground:after {
	content: '';
	position: absolute;
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	background: rgba(0, 0, 0, 0.1);
	opacity: 0;
	border-radius: var(--radius-button);
	transition: all 0.3s;
	-webkit-transition: all 0.3s;
	-moz-transition: all 0.3s;
} */

/* .button-darkBackground:hover:after {
	opacity: 1;
} */

/* .button-darkBackground:hover { */

/* background-color: transparent;
    color: var(--text-secondary);
    box-shadow: var(--elevation-raised);
    -webkit-box-shadow: var(--elevation-raised);
    -moz-box-shadow: var(--elevation-raised); */

/* } */

.button-img {
	height: 2rem;
	width: 2rem;
	background-size: cover;
	background-repeat: no-repeat;
	background-position: center;
	padding: var(--pad-card);
}

.button-imgAndText {
	display: flex;
	gap: var(--gap-stack);
	justify-content: start;
	padding: var(--pad-dense) var(--pad-card);
}

.button-textOnly {
	font-size: var(--font-size-lead);
	padding-top: .3rem;
	/* intentional literal: optical baseline nudge, not spacing rhythm */
}

.button-textOnly:enabled:hover {
	box-shadow: none;
	text-shadow: var(--text-shadow-hover);
}

.button-textOnly:disabled {
	border: none;
}

/* Sizes — ordered after `.button-textOnly` so size wins the equal-specificity font-size tie when both classes apply. */

.button-small {
	font-size: var(--font-size-label);
}

.button-medium {
	font-size: var(--font-size-body);
}

.button-large {
	font-size: var(--font-size-subheading);
}

:root[data-viewport="phone"] .button-lightBackground,
:root[data-viewport="phone"] .button-darkBackground {
	min-height: var(--touch-target-primary);
	min-width: var(--touch-target-primary);
}

.roundedCornerInput,
.dropdown {
	border: var(--border-width) solid var(--border-default);
	color: var(--text-primary);
	accent-color: var(--brand-primary);
	border-radius: var(--radius-input);
	font: inherit;
	font-family: var(--font-body);
	text-align: left;
	padding: var(--pad-input) var(--pad-input-inline);
	background: var(--surface-sunken);
	box-shadow: var(--elevation-inset);
}

.roundedCornerInput::placeholder,
.dropdown::placeholder {
	color: var(--text-secondary);
}

.roundedCornerInput:disabled,
.dropdown:disabled {
	color: var(--text-disabled);
	border-color: var(--border-default);
}

/* Native <select> (getDropdownMenu) carries no class — theme the bare element
   so it re-skins in every theme/mode instead of staying browser-native white.
   appearance:none drops the native chrome; a token-neutral chevron replaces it. */
select {
	appearance: none;
	-webkit-appearance: none;
	border: var(--border-width) solid var(--border-default);
	border-radius: var(--radius-input);
	color: var(--text-primary);
	font: inherit;
	font-family: var(--font-body);
	padding: var(--pad-input) var(--pad-input-inline);
	padding-right: 3.2rem;
	/* intentional literal: chevron clearance paired with `background-position: right 1.1rem`, not spacing rhythm */
	background-color: var(--surface-sunken);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23888888' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 1.1rem center;
	background-size: 1.1rem;
	box-shadow: var(--elevation-inset);
	cursor: pointer;
}

select:disabled {
	color: var(--text-disabled);
	cursor: not-allowed;
}

/* Open option list is OS-native; bg/color honored where the platform allows. */
.option {
	color: var(--text-primary);
	background: var(--surface-card);
}

.heading,
.stringNode,
.span,
.label {
	color: var(--text-primary);
}

.heading {
	font-family: var(--font-display);
	text-align: center;
	width: auto;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.headingStyledInput {
	border: none;
	text-align: left;
	cursor: pointer;
}

.textEllipsis {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* .headingStyledInput:focus::placeholder {
    color: transparent;
} */

.editableHeading,
.editableBody {
	text-align: left;
	cursor: pointer;
	text-overflow: ellipsis;
	max-width: 100%;
}

.editableHeading:empty:before,
.editableBody:empty:before {
	content: attr(data-placeholder);
}

.editableHeading:focus:before,
.editableBody:focus:before {
	background-color: var(--state-selection-highlight);
}

.stringNode,
.span {
	font-family: var(--font-body);
	width: fit-content;
	height: fit-content;
	white-space: pre-wrap;
	text-align: left;
}

.badge {
	display: inline-flex;
	align-items: center;
	line-height: 1.5;
	padding: 0 var(--pad-dense);
	border: var(--border-shorthand);
	border-radius: var(--radius-pill);
	white-space: nowrap;
}

/* Backgrounds/text come from the --Badge_* constants in app.css, which derive
   from the themeable palette — so badges re-theme with the active theme /
   per-entity customization. Border matches the fill so each pill reads as a solid
   chip; all filled tones use the on-fill font color for contrast, while the
   outline-only neutral badge (transparent fill) keeps the standard font color. */
.badge-neutral {
	background: var(--Badge_Neutral_Background);
	color: var(--Badge_Neutral_Font_Color);
}

.badge-highlight {
	background: var(--Badge_Highlight_Background);
	border-color: var(--Badge_Highlight_Background);
	color: var(--Badge_On_Fill_Font_Color);
}

.badge-success {
	background: var(--Badge_Success_Background);
	border-color: var(--Badge_Success_Background);
	color: var(--Badge_On_Fill_Font_Color);
}

.badge-warning {
	background: var(--Badge_Warning_Background);
	border-color: var(--Badge_Warning_Background);
	color: var(--Badge_On_Fill_Font_Color);
}

.badge-partial {
	background: var(--Badge_Partial_Background);
	border-color: var(--Badge_Partial_Background);
	color: var(--Badge_On_Fill_Font_Color);
}

.badge-danger {
	background: var(--Badge_Danger_Background);
	border-color: var(--Badge_Danger_Background);
	color: var(--Badge_On_Fill_Font_Color);
}

.stringNode-muted {
	opacity: 0.6;
	font-style: italic;
	text-align: center;
	display: block;
}

/* Empty-container placeholder: muted message + optional CTA. Stacks vertically
   and centers in whatever region hosts it. The flex/align stack applies to
   every consumer (bucket empties, dropdowns, TaskTime). */
.emptyState {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--gap-stack);
	width: 100%;
}

/* Decorative context icon above the muted message. Muted-to-match so the icon
   reads as a soft visual anchor, not a competing focal point with the CTA. */
.emptyState__icon {
	opacity: 0.4;
}

.emptyState__action {
	flex: none;
}

.heading-smaller,
.stringNode-smaller,
.span-smaller,
.label-smaller,
.option-smaller,
.input-smaller,
.anchor-smaller {
	font-size: var(--font-size-label);
}

.heading-small,
.stringNode-small,
.span-small,
.label-small,
.option-small,
.input-small,
.anchor-small {
	font-size: var(--font-size-caption);
}

.heading-medium,
.stringNode-medium,
.span-medium,
.label-medium,
.option-medium,
.input-medium,
.anchor-medium {
	font-size: var(--font-size-lead);
}

.heading-large,
.stringNode-large,
.span-large,
.label-large,
.option-large,
.input-large,
.anchor-large {
	font-size: var(--font-size-heading);
}

.heading-larger,
.stringNode-larger,
.span-larger,
.label-larger,
.option-larger,
.input-larger,
.anchor-larger {
	font-size: var(--font-size-stat);
}

.input-smaller {
	height: 1.5rem;
}

.input-small {
	height: 2rem;
}

.input-medium {
	height: 2.5rem;
}

.input-large {
	height: 3rem;
}

.input-larger {
	height: 3.5rem;
}

:root[data-viewport="phone"] .roundedCornerInput:not([type="range"]):not([type="color"]) {
	min-height: var(--touch-target-primary);
}

.errorNotice {
	color: var(--status-danger);
}

.heading-light,
.stringNode-light,
.span-light,
.label-light,
.option-light {
	font-weight: 300;
}

.heading-normal,
.stringNode-normal,
.span-normal,
.label-normal,
.option-normal {
	font-weight: 400;
}

.heading-bold,
.stringNode-bold,
.span-bold,
.label-bold,
.option-bold {
	font-weight: 500;
}

.heading-inverted,
.stringNode-inverted,
.span-inverted,
.label-inverted,
.chip-inverted,
.option-inverted {
	color: var(--text-on-brand);
}

.checkbox {
	appearance: none;
	-webkit-appearance: none;
	margin: 0;
	flex-shrink: 0;
	position: relative;
	display: inline-block;
	background: var(--surface-sunken);
	border: var(--border-width) solid var(--border-default);
	border-radius: var(--radius-input);
	box-shadow: var(--elevation-inset);
	cursor: pointer;
	transition: background var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard);
}

/* Checkmark — themed ink on the brand fill, revealed on :checked. Absolutely
   positioned so the % size resolves against the (definite) box, not a
   content-sized grid track (which collapsed it to 0). */
.checkbox::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 58%;
	height: 58%;
	transform: translate(-50%, -50%) scale(0);
	transition: transform var(--motion-fast) var(--ease-standard);
	background: var(--text-on-brand);
	clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
}

.checkbox:checked {
	background: var(--brand-primary);
	border-color: var(--brand-primary);
}

.checkbox:checked::after {
	transform: translate(-50%, -50%) scale(1);
}

.checkbox:disabled {
	cursor: not-allowed;
	opacity: 0.5;
}

.checkbox-small {
	height: 1.2rem;
	width: 1.2rem;
}

.checkbox-medium {
	height: 1.5rem;
	width: 1.5rem;
}

.checkbox-large {
	height: 2.2rem;
	width: 2.2rem;
}

.checkbox-larger {
	height: 3rem;
	width: 3rem;
}

.scrollArea {
	overflow: hidden;
	display: block;
	scroll-behavior: smooth;
	height: 100%;
	min-height: 0;
	scrollbar-gutter: stable both-edges;
}

.scrollArea:hover {
	overflow-y: auto;
}

.listItem {
	margin: var(--gap-stack) var(--pad-card);
	font-size: var(--font-size-body);
}

.option {
	margin: var(--gap-stack) var(--pad-card);
	cursor: pointer;
}

/* pillBox is flat/token-driven: modern/futuristic/neumorph all express through
   role tokens (surface + radius + elevation + clip). The cyber neon double-frame
   (::before/::after clip-path layers) is the ONE structural exception and lives
   in themes/cyber.css under @layer theme — NOT here. The old
   `.pillBox-{CLASSIC,CYBER}_STYLE_MODE` selector blocks are removed: no factory
   emits them anymore (getPillBox de-baked of getStyleMode). */
.pillBox {
	display: block;
	padding: var(--pad-card);
	background: var(--surface-card);
	border-radius: var(--radius-card);
	box-shadow: var(--elevation-raised);
	clip-path: var(--surface-clip, none);
}

/* Chip: compact pillBox variant — thin-border outline instead of the raised
   pillBox surface. inline-flex so chip rows wrap naturally. */
.chip {
	height: fit-content;
	width: fit-content;
	display: inline-flex;
	align-items: center;
	padding: 0 var(--pad-dense);
	background: transparent;
	box-shadow: none;
	border: var(--border-width) solid var(--border-default);
}

.img {
	width: auto;
	height: auto;
}

.img-round {
	border-radius: var(--radius-avatar);
}

.textArea {
	width: 100%;
	height: 3rem;
	display: block;
	background: var(--surface-sunken);
	color: var(--text-primary);
	border: var(--border-width) solid var(--border-default);
	border-radius: var(--radius-input);
	box-shadow: var(--elevation-inset);
	padding: var(--pad-input) var(--pad-input-inline);
	font: inherit;
	font-family: var(--font-body);
	margin: var(--gap-stack) 0;
}

.textArea::placeholder {
	color: var(--text-secondary);
}

/* Looks like a link out of the box — underline + brand color + pointer. Font size
 * comes from the `anchor-${size}` class (see the size groups above), so no size is
 * hard-coded here (a hard-coded value here would win by source order and defeat it). */
.anchor,
.anchor:visited {
	text-decoration: underline;
	color: var(--brand-primary);
	width: fit-content;
	cursor: pointer;
}

.anchor:active,
.anchor:hover {
	color: var(--brand-accent);
}

.link {
	text-decoration: none;
	color: inherit;
}

.iframe {
	height: 100%;
	width: 100%;
}

.hiddenUpload {
	display: none;
}

.colorInput {
	border: none;
	/* display: none; */
	opacity: 0;
	height: 100%;
	width: 100%;
}

.colorInput-visible {
	height: 2rem;
	width: 2rem;
	display: block;
	border-radius: var(--radius-circle);
	box-shadow: var(--elevation-raised);
}

.colorInput-visible:active,
.colorInput-visible:active .colorInput-visible {
	box-shadow: none;
}

.sliderContainer {
	position: relative;
	height: 1.8rem;
	width: 15rem;
	display: block;
}

/* The range input itself is the TRACK — flatten the inherited
   roundedCornerInput/input-medium border+padding so only the rail shows. */
.sliderInput {
	appearance: none;
	-webkit-appearance: none;
	margin: 0;
	padding: 0;
	border: none;
	min-height: 0;
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	inset-inline: 0;
	width: 100%;
	height: .6rem;
	background: var(--surface-sunken);
	box-shadow: var(--elevation-inset);
	border-radius: var(--radius-pill);
	cursor: pointer;
}

/* Filled portion (JS sets width to value%). */
.sliderProgress {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	inset-inline-start: 0;
	height: .6rem;
	background: var(--brand-primary);
	border-radius: var(--radius-pill);
	pointer-events: none;
}

.sliderInput::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	cursor: pointer;
	background: var(--brand-primary);
	height: 1.6rem;
	width: 1.6rem;
	border-radius: var(--radius-avatar);
	border: 0.2rem solid var(--surface-card);
	box-shadow: var(--elevation-raised);
	transition: transform var(--motion-fast) var(--ease-standard);
}

.sliderInput::-moz-range-thumb {
	appearance: none;
	cursor: pointer;
	background: var(--brand-primary);
	height: 1.6rem;
	width: 1.6rem;
	border-radius: var(--radius-avatar);
	border: 0.2rem solid var(--surface-card);
	box-shadow: var(--elevation-raised);
	transition: transform var(--motion-fast) var(--ease-standard);
}

.sliderInput::-webkit-slider-thumb:hover {
	transform: scale(1.12);
}

.sliderInput::-moz-range-thumb:hover {
	transform: scale(1.12);
}

.tile {
	display: flex;
	position: relative;
	height: fit-content;
	padding: var(--pad-dense) var(--pad-card);
	background-color: var(--surface-card);
	border-radius: var(--radius-card);
	box-shadow: var(--elevation-flat);
	clip-path: var(--surface-clip, none);
	-webkit-backdrop-filter: var(--surface-blur, none);
	backdrop-filter: var(--surface-blur, none);
}

.tile-bordered {
	border: var(--border-width) solid var(--border-default);
}

/*#region: progress bar */
.progressBarContainer {
	background-color: var(--surface-sunken);
	border-radius: var(--radius-input);
	width: 100%;
	height: .6rem;
}

.progressBar {
	background-color: var(--brand-primary);
	height: 100%;
	border-radius: inherit;
	display: block;
}

/*#endregion: progress bar */
.headerWithSmallHeading__smallHeading {
	display: block;
	white-space: nowrap;
	text-overflow: ellipsis;
	line-height: 1rem;
}

.headerWithSmallHeading__header {
	display: block;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	line-height: 2rem;
}

:user-invalid {
	border-color: var(--status-danger);

	&[type="file"] {
		color: var(--status-danger);
	}
}

.loadingPlaceholder {
	height: 1.5rem;
	min-width: 9rem;
	position: relative;
	border-radius: var(--radius-card);
	background-color: var(--surface-hover);
	overflow: hidden;
}

.loadingPlaceholder-input {
	background-color: var(--surface-selected);
	height: 2.5rem;
	border: var(--border-width) solid var(--border-default);
	border-radius: var(--radius-input);
}

.loadingPlaceholder::after {
	content: '';
	animation: slide 1s linear infinite;
	border-radius: var(--radius-card);
	position: absolute;
	background-image: linear-gradient(to right, var(--surface-hover), var(--surface-selected), var(--surface-hover));
	height: 100%;
	width: 50%;
}

.loadingPlaceholder-input::after {
	background-image: linear-gradient(to right, var(--surface-selected), var(--surface-hover), var(--surface-selected));
}

/* Round modifier for avatar / icon-circle skeletons — square + fully rounded so
   it mirrors an EntityDisplayImage / card icon while sharing the one shimmer. */
.loadingPlaceholder-circle {
	min-width: 0;
	width: 3.6rem;
	height: 3.6rem;
	flex-shrink: 0;
	border-radius: var(--radius-avatar);
}

/* Skeleton card — mirrors the locked detail-card stack (icon circle + label,
   tall value, supporting line(s)) so loading → loaded doesn't reflow. Surface +
   pad come from role tokens, never literals. */
.skeletonCard {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	padding: var(--pad-card);
	background: var(--surface-sunken);
	border-radius: var(--radius-card);
}

.skeletonCard__header {
	display: flex;
	align-items: center;
	gap: var(--gap-stack);
}

.skeletonCard__label {
	height: 1.2rem;
	min-width: 6rem;
	flex: 1;
}

.skeletonCard__value {
	height: 3rem;
	min-width: 7rem;
}

.skeletonCard__supporting {
	height: 1.2rem;
	min-width: 5rem;
}

/* Skeleton row — avatar circle + two stacked text lines, mirroring a tile/list
   row so list loading → loaded doesn't reflow. */
.skeletonRow {
	display: flex;
	align-items: center;
	gap: var(--gap-stack);
	padding: var(--pad-dense) var(--pad-card);
}

.skeletonRow__lines {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	flex: 1;
	min-width: 0;
}

.skeletonRow__line {
	height: 1.2rem;
	min-width: 0;
	width: 70%;
}

.skeletonRow__line--sub {
	height: 1rem;
	width: 45%;
}

.form {
	position: relative;
}

.form-label {
	position: absolute;
	justify-self: end;
	font-size: var(--font-size-label);
	color: var(--status-danger);
	right: 0;
}

:root[data-viewport="phone"] .form-label {
	font-size: var(--font-size-caption);
}

/* Shimmer sweep. Pure `transform` so it stays on the compositor — animating
   `left` here forced a layout + paint pass every frame, forever, once per
   skeleton on screen. Endpoints are equivalent, not merely similar: the
   pseudo-element is `width: 50%` of its parent with no `left` (static position
   `left: 0`), and percentage `translateX` resolves against the element's OWN
   width, so -100% of own = the old -50% of parent and 300% of own = the old
   150%. The base rule at `.loadingPlaceholder::after` needs no change. */
@keyframes slide {
	0% {
		transform: translateX(-100%);
	}

	100% {
		transform: translateX(300%);
	}
}

/* Reduced-motion guard: the shimmer animation rides on `.loadingPlaceholder::after`
   (and inherits to the `-circle` modifier) — kill it for users who opt out of
   motion. The placeholder still reads as a muted surface block, just static. */
@media (prefers-reduced-motion: reduce) {

	.loadingPlaceholder,
	.loadingPlaceholder::after,
	.loadingPlaceholder-circle,
	.loadingPlaceholder-circle::after {
		animation: none;
	}
}

/**
* compoundElements.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-17 Phone rules re-gated :root[data-mobile] → :root[data-viewport="phone"] (decision 0004 phase 1, #1684)
* @version 2026-July-29 Spacing / radius / type literals collapsed onto the app.css
*   role-token ladder. Retained literals carry an inline `intentional literal` note.
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
*/

.imgWithHeading-view {
	display: flex;
	flex-direction: column;
}

.imgWithHeading-pic {
	height: 5rem;
	width: auto;
}

.barSeparatedDateTime-view {
	display: flex;
	height: 2rem;
	width: auto;
	align-self: top;
}

/* intentional literal (the three margins below): 1-2px optical baseline alignment
   of the |-separated date/time trio, not spacing rhythm — a spacing token would
   break the alignment. The `auto` legs are positional, not rhythm. */
.barSeparatedDateTime-bar {
	height: 100%;
	margin: .2rem .5rem auto .5rem;
}

.barSeparatedDateTime-date {
	margin: .1rem 0 auto auto;
}

.barSeparatedDateTime-time {
	margin: .1rem auto auto 0;
}

.initialsRoundHeading__view {
	display: flex;
	border-radius: var(--radius-avatar);
	background-color: var(--surface-raised);
	color: var(--text-primary);
	height: fit-content;
	width: fit-content;
	align-items: center;
	justify-content: center;
}

/* intentional literal (the five -<size> paddings below): per-size OPTICAL tuning
   that keeps a `fit-content` box circular under --radius-avatar. The block axis is
   non-monotonic (.2 .2 .5 .4 .2), which is what proves it is optical rather than a
   spacing ladder — uniform tokens would break circularity at every size. */
.initialsRoundHeading__view-smaller {
	padding: .2rem .6rem;
}

.initialsRoundHeading__view-small {
	padding: .2rem .7rem;
}

.initialsRoundHeading__view-medium {
	padding: .5rem 1rem;
}

.initialsRoundHeading__view-large {
	padding: .4rem 1rem;
}

.initialsRoundHeading__view-larger {
	padding: .2rem 1.2rem;
}

/* Sibling of initialsRoundHeading: a round image leaf. No background-color — it
   stays transparent until getRoundImage paints a loaded picture, so when it is
   layered over an initials placeholder the initials show through as the fallback. */
.roundImage__view {
	background-position: center;
	background-repeat: no-repeat;
	border-radius: var(--radius-avatar);
}

.roundImage__view-small {
	height: 2.5rem;
	width: 2.5rem;
}

.roundImage__view-medium {
	height: 3rem;
	width: 3rem;
}

.roundImage__view-large {
	height: 4rem;
	width: 4rem;
}

.roundImage__view-larger {
	height: 5rem;
	width: 5rem;
}

/* Round figure: a round container layering the initials placeholder with a
   getRoundImage overlay (.roundFigure__image) that covers it once a picture loads.
   .roundFigure__image is shared with EntityDisplayImage's reactive layering, so the
   overlay positioning lives in one place. */
.roundFigure__view {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--radius-avatar);
	background-color: var(--surface-raised);
}

.roundFigure__view-small {
	height: 2.5rem;
	width: 2.5rem;
}

.roundFigure__view-medium {
	height: 3rem;
	width: 3rem;
}

.roundFigure__view-large {
	height: 4rem;
	width: 4rem;
}

.roundFigure__view-larger {
	height: 5rem;
	width: 5rem;
}

.roundFigure__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

.getIconHeadingTab__tabButtons {
	display: grid;
	grid-template-columns: auto 1fr;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	gap: var(--gap-stack);
}

.getIconHeadingTab__tabIcon {
	margin: auto;
}

.getIconHeadingTab__tabButtonText {
	position: relative;
	top: .2rem;
	margin-right: auto;
}

/* Dialog */

.dialog__view {
	display: block;
	width: 100dvw;
	height: 100dvh;
}

.dialog__view-translucentBlack {
	background-color: var(--surface-overlay);
}

.dialog__content {
	padding: var(--pad-sheet);
	max-width: 50rem;
	position: absolute;
	display: grid;
	grid-template-areas: 'dialog__content_text dialog__content_text' '. dialog__content_button';
	grid-template-columns: repeat(2, 1fr);
	grid-template-rows: 1fr auto;
	left: 50%;
	top: 10rem;
	transform: translate(-50%, -50%);
}

.dialog__heading {
	grid-area: dialog__content_text;
}

.dialog__commitButton {
	margin-left: var(--gap-section);
}

.buttons__container {
	grid-area: dialog__content_button;
	margin: auto 1rem auto auto; /* intentional literal: positional (`auto` centering) margin, not spacing rhythm */
}

:root[data-viewport="phone"] .dialog__button,
:root[data-viewport="phone"] .dialog__commitButton {
	min-width: var(--touch-target-primary);
	min-height: var(--touch-target-primary);
}

/* Show Msg */

.showMsg {
	position: absolute;
	top: 3rem;
	right: 0;
	transform: translateX(110%);
	box-shadow: var(--elevation-overlay);
	padding: var(--pad-button) var(--pad-card);
	cursor: pointer;
}

.showMsg-visible {
	transform: translateX(-5rem);
}

/* Custom Tile */

.customTile__tiles {
	padding: 0;
	border-radius: var(--radius-shell);
}

.customTile__headerContainer {
	width: 100%;
	background-color: var(--surface-sunken);
	display: flex;
	align-items: center;
	border-radius: var(--radius-shell) var(--radius-shell) 0 0;
	padding: var(--pad-button) 0;
}

.customTile__heading {
	color: var(--text-on-brand);
	font-size: var(--font-size-heading);
	font-weight: 600;
	margin-left: var(--gap-section);
}

/* Search Bar */

.searchBar {
	background-image: url('../../img/SearchIcon.svg');
	background-repeat: no-repeat;
	background-position: right 1rem center;
	background-size: 1.3rem 1.3rem;
	padding-right: 2.5rem; /* intentional literal: search-icon clearance paired with `background-position: right 1rem center`, not spacing rhythm */
	background-color: var(--surface-sunken);
	width: 100%;
}

.getTextEditArea__container {
	height: 5rem;
	width: 10rem;
}

/**
* pillboxWithHeading.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

/* Deep-theming Phase 7: one stable structure painting from tokens. The cyber neon
   frame is inherited from the shared `.pillBox` [data-theme="cyber"] rule
   (baseElements) — no per-theme variant block here. */
.pillboxWithHeading__view {
	position: relative;
	display: grid;
	gap: var(--gap-stack);
	grid-template-rows: auto 1fr;
	padding: var(--pad-card);
}

.pillboxWithHeading__title {
	border-bottom: var(--border-shorthand);
	padding-bottom: var(--pad-dense);
	text-align: left;
}

/**
* expandableTileContainer.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
*/

.expandableTileContainer__view {
    display: flex;
}

.expandableTileContainer__background {
    position: fixed;
    width: 100dvw;
    height: 100dvh;
    z-index: 2;
    top: 0;
    left: 0;
}

.expandableTileContainer__tileContainer {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: visible;
}

/* `transition: none`, not the old `.0001s` fake-instant: the two `-expanded-*`
   modifiers below are same-specificity rules declared later and are applied
   together with this one by ExpandableTileContainer.js, so they win and the
   expand still animates. Spelling the intent as `none` keeps the behavior
   identical today and survives a future class-order flip. */
.expandableTileContainer__tileContainer-expanded {
    transition: none;
    z-index: 10;
    overflow: hidden;
}

/* TODO: these animate `top`/`left`/`height`/`width` (written in px by
   ExpandableTileContainer.js:59-87), forcing layout + paint every frame. The
   real fix is FLIP — measure, then animate `transform: translate() scale()` —
   which needs the JS rewritten. Halving the duration halves the cost. */
.expandableTileContainer__tileContainer-expanded-fixed {
    transition: all var(--motion-slow) var(--ease-enter);
    position: fixed;
}

.expandableTileContainer__tileContainer-expanded-absolute {
    transition: all var(--motion-slow) var(--ease-enter);
    position: absolute;
}
/**
* entityDisplayImage.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-07-30 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.entityDisplayImage__view {
	position: relative;
	background-position: center;
	background-repeat: no-repeat;
	border-radius: var(--radius-circle);
	cursor: pointer;
	border: .1rem solid transparent;
	background-color: var(--surface-raised);
}

/* The avatar's image overlay is shared with getRoundFigure (.roundFigure__image,
   positioned in compoundElements.css). The view is position:relative above so that
   overlay anchors to it; the initials layer shows through until a picture loads. */

/* Cyber angular silhouette — ported to the [data-theme] gate (the view no longer
   bakes a -CYBER_THEME class; see EntityDisplayImage.js). */
:root[data-theme="cyber"] .entityDisplayImage__view {
	border-radius: 0;
	clip-path: polygon(0.5rem 65%, 35% calc(100% - 0.5rem), calc(100% - 0.5rem) calc(100% - 0.5rem), calc(100% - 0.5rem) 0.5rem, 0.5rem 0.5rem);
}

/* Match the cyber clip on the image overlay so a loaded picture takes the same
   angular silhouette as the view (clip-path on the parent does not clip children). */
:root[data-theme="cyber"] .entityDisplayImage__view .roundFigure__image {
	border-radius: 0;
	clip-path: polygon(0.5rem 65%, 35% calc(100% - 0.5rem), calc(100% - 0.5rem) calc(100% - 0.5rem), calc(100% - 0.5rem) 0.5rem, 0.5rem 0.5rem);
}

.entityDisplayImage__view-small {
	height: 2.5rem;
	width: 2.5rem;
}

.entityDisplayImage__view-medium {
	height: 3rem;
	width: 3rem;
}

.entityDisplayImage__view-large {
	height: 4rem;
	width: 4rem;
}

.entityDisplayImage__view-larger {
	height: 5rem;
	width: 5rem;
}

.entityDisplayImage__view-highlighted {
	border-color: var(--brand-accent);
}

.entityDisplayImage__view-hover {
	box-shadow: var(--elevation-overlay);
}

/**
* icon.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-05-28 Initial Version
* @version 2026-July-03 Button-variant UA reset; cursor:pointer gated to clickable (button) icons (#731)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-July-31 tasks.svg / image.svg lost their baked hex fill blocks (`.cls-1{fill:#404a5e}` / `.st0{fill:#808789}`), so both icons now inherit `.icon__view { fill: currentColor }` app-wide. Affects tasks.svg's nav-rail (`TasksView.static icon`) + ActivityModule/ProjectActiveTasks/TaskActivity, and image.svg's StylePropTile.js use — intentional (a baked hex can't theme), but a visual pass in both modes was expected. Splash size (`.icon__svg-splash` / `.icon__view-splash`, 20rem) added for the #1764 empty-state hero, capped with `max-width:100%; max-height:100%` for narrow phone-band hosts.
*/

.icon__view {
	fill: currentColor;
	transition: 0s;
	display: flex;
	width: fit-content;
	position: relative;
}

/* Clickable icons are real <button>s (#731). Reset the UA button chrome so the
   button variant renders byte-identical to the historical div; :where() keeps
   specificity at zero so any existing .icon__view override still wins. Only the
   clickable variant is a pointer target, so cursor rides here (non-clickable
   icons used to get a misleading pointer cursor). */
.icon__view:where(button) {
	appearance: none;
	background: none;
	border: none;
	padding: 0;
	margin: 0;
	font: inherit;
	color: inherit;
	text-align: inherit;
	cursor: pointer;
}

.icon__view:where(button):disabled {
	cursor: default;
}

.icon__badge {
	position: absolute;
	top: -.8rem;
	left: -.8rem;
	background: var(--brand-primary);
	color: var(--text-on-brand);
	border-radius: var(--radius-card);
	min-width: 1.6rem;
	height: 1.6rem;
	padding: 0 var(--pad-cell);
	font-size: var(--font-size-label);
	line-height: 1.6rem;
	text-align: center;
}

.icon__badge-hidden {
	display: none;
}

.icon__svg {
	fill: inherit;
	transition: 0s;
	height: 100%;
	width: 100%;
}

.icon__heading {
	color: currentColor;
	display: none;
}

.icon__svg-small,
.icon__view-small {
	height: 1.2rem;
	width: 1.2rem;
}

.icon__svg-medium,
.icon__view-medium {
	height: 1.5rem;
	width: 1.5rem;
}

.icon__svg-large,
.icon__view-large {
	height: 2rem;
	width: 2rem;
}

.icon__svg-larger,
.icon__view-larger {
	height: 2.5rem;
	width: 2.5rem;
}

.icon__svg-splash,
.icon__view-splash {
	height: 20rem;
	width: 20rem;
	max-width: 100%;
	max-height: 100%;
}

.icon__svg-disabled {
	opacity: 0.6;
	pointer-events: none;
}
/**
 * floatingExpandablePanel.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2020-04-10 Initial Version
 * @version 2026-July-03 Root is a native non-modal <dialog> (#335): UA-style neutralization + display scoped to [open]
 * @version 2026-July-05 Neutralize the UA dialog max-width/max-height too — they compute against the CONTAINING BLOCK (the anchor's short position:relative box), clipping the expanded list to ~one option (seen on NewEntityPanel's type dropdown)
 * @version 2026-July-14 CSS Anchor Positioning + popover="manual" (#1619). Design: knowledge-base/architecture/frontend.md
 * @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the close button always (#1641)
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 */

.floatingExpandablePanel__view {
	width: fit-content;
	/* max(content, anchor) — dropdowns match trigger width, wider content wins. */
	min-width: anchor-size(width);
	/* Fixed (not absolute): position-try-fallbacks checks overflow against the containing block; fixed makes that the viewport. */
	position: fixed;
	position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
	box-shadow: var(--elevation-overlay);
	border-radius: var(--radius-card);
	background-color: var(--surface-card);
	z-index: 2;
	/* Neutralize UA <dialog> styles (margin auto, border solid, padding 1em, inset-inline 0, color CanvasText). */
	/* margin-inline: 0 keeps the panel flush with the anchor's inline edge; a uniform margin misaligns it. */
	margin-block: 0.25rem; /* intentional literal: anchor-positioning offset between trigger and popover — positioning, not density */
	margin-inline: 0;
	border: none;
	padding: 0;
	inset: auto;
	color: inherit;
	/* UA caps an open dialog at calc((100% - 6px) - 2em) of its containing block — the real height budget is the JS-set maxHeight on __expandArea. */
	max-width: none;
	max-height: none;
}

/* Scoped to open state — an unconditional display:grid would override the UA's closed display:none and leak the collapsed panel. */
.floatingExpandablePanel__view:popover-open,
.floatingExpandablePanel__view[open] {
	display: grid;
}

.floatingExpandablePanel__expandArea {
	max-height: 0;
	width: 100%;
	overflow: hidden;
	border-radius: var(--radius-card);
}

/* Each anchor variant picks a cell of the 3×3 position-area grid; the shared position-try-fallbacks (on the base rule) flips block/inline/both on overflow. */
.floatingExpandablePanel__anchor-bottomLeft {
	position-area: bottom span-right;
}

.floatingExpandablePanel__anchor-bottomRight {
	position-area: bottom span-left;
}

.floatingExpandablePanel__anchor-topLeft {
	position-area: top span-right;
}

.floatingExpandablePanel__anchor-topRight {
	position-area: top span-left;
}

.floatingExpandablePanel__closeButton {
	width: 2rem;
	height: 2rem;
	display: flex;
	align-items: center;
	justify-content: center;
	position: absolute;
	top: 0;
	right: 0;
	z-index: 3;
	transform: translate(50%, -50%);
	border-radius: var(--radius-shell);
	background-color: var(--surface-sunken);
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the close button behind it — touch devices see it always. */
@media (hover: hover) {
	.floatingExpandablePanel__closeButton {
		opacity: 0;
	}

	.floatingExpandablePanel__view:hover .floatingExpandablePanel__closeButton {
		opacity: 1;
	}
}

/*  */

/* .floatingExpandablePanel__view:focus .floatingExpandablePanel__expandArea {
    width: fit-content;
    max-height: 20rem;
    padding: 0.5rem;
} */
/**
* toggleTextButton.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
*/

.toggleTextButton__view {
    cursor: pointer;
}
/**
* addTimeIcon.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-18 Initial Version
* @version 2026-August-14 Glyph + ring whites tokenized: --text-on-brand on the accent fill, --text-on-status on the success fill, --border-width/--surface-card for the separation ring (#1840)
*/

.addTimeIcon__view, .addTimeIcon__plusSign {
    height: 2.1rem;
    width: 2.1rem;
    background-color: var(--brand-accent);
    border-radius: var(--radius-shell);
    position: relative;
    border: var(--border-width) solid var(--surface-card);
}

.addTimeIcon__view::before, .addTimeIcon__view::after {
    content: '';
    position: absolute;
    border-radius: var(--radius-shell);
    background-color: var(--text-on-brand);
    height: 40%;
    width: .1rem;
    transform: translate(.95rem, .3rem);
}

.addTimeIcon__view::after {
    height: 30%;
    transform: translate(.7rem, .85rem) rotate(75deg);
}

.addTimeIcon__plusSign {
    background-color: var(--status-success);
    height: 1rem;
    width: 1rem;
    position: absolute;
    transform: translate(1.1rem, 1.1rem);
}

.addTimeIcon__plusSign::before, .addTimeIcon__plusSign::after {
    content: '';
    position: absolute;
    border-radius: var(--radius-shell);
    background-color: var(--text-on-status);
    height: 50%;
    width: .1rem;
    transform: translate(.35rem, .2rem);
}

.addTimeIcon__plusSign::after {
    transform: translate(.35rem, .2rem) rotate(90deg);
}

/**
* playPauseToggleButton.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Retained-literal pragma on the clip-path triangle's optical centring pad
* @version 2026-August-14 Triangle reads --text-on-brand — it is drawn over both the accent fill and the retuned --text-disabled rest fill (#1840)
*/

/* Modern (default / :root) is the base; the cyber neon frame + sizing rides the
   [data-theme="cyber"] gate (deep-theming Phase 7 — de-baked from the old
   `-${theme}` JS class suffixes). */
.playPauseToggleButton__view {
	display: grid;
	align-content: center;
	justify-content: center;
	height: 2.1rem;
	width: 2.1rem;
	padding-left: .2rem; /* intentional literal: 2px optical centring for the clip-path triangle inside a 2.1rem box, not spacing rhythm */
	background-color: var(--text-disabled);
	border-radius: var(--radius-shell);
}

.playPauseToggleButton__noPadding {
	padding: 0;
}

.playPauseToggleButton__backgroundColor {
	background-color: var(--brand-accent);
}

.playPauseToggleButton__view:disabled {
	background-color: var(--text-disabled);
}

.playPauseToggleButton__view-disabled {
	opacity: .6;
	pointer-events: none;
}

.playPauseToggleButton__stop {
	margin: auto;
	height: 1rem;
	width: 1rem;
	background-color: var(--text-on-brand);
	clip-path: polygon(0 0, 100% 50%, .0rem 100%);
	-webkit-clip-path: polygon(0 0, 100% 50%, .0rem 100%);
	-moz-clip-path: polygon(0 0, 100% 50%, .0rem 100%);
}

.playPauseToggleButton__play {
	clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
	-webkit-clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
	-moz-clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
}

/* ---- Cyber: angular container + neon ::after frame (was .__cyberContainer +
   .__view-CYBER_THEME, applied via JS; now gated on the data-theme attribute) ---- */
:root[data-theme="cyber"] .playPauseToggleButton__view {
	height: 2.9rem;
	width: 2.6rem;
	background-color: transparent;
	border-radius: 0;
	position: relative;
	cursor: pointer;
	clip-path: polygon(0% 0%, 0% 70%, 25% 100%, 65% 100%, 67% 97%, 97% 97%, 100% 94%, 100% 20%, 80% 0%, 0% 0%);
}

:root[data-theme="cyber"] .playPauseToggleButton__view::after {
	content: '';
	background-color: var(--surface-raised);
	position: absolute;
	clip-path: polygon(0% 0%, 0% 70%, 25% 100%, 65% 100%, 67% 97%, 97% 97%, 100% 94%, 100% 20%, 80% 0%, 5% 0%, 5% 1px, calc(80% - 0.5px) 1px,
			calc(100% - 1px) calc(20% + 0.5px), calc(100% - 1px) 86%, calc(14% + 1px) 86%, 1px calc(70% - 0.5px), 1px 33%, 9% 27%, 9% 0%);
	height: 100%;
	width: 100%;
}

/* In cyber the play-state fill colours the ::after frame, not the box. */
:root[data-theme="cyber"] .playPauseToggleButton__backgroundColor::after {
	background-color: var(--brand-accent);
}

:root[data-theme="cyber"] .playPauseToggleButton__stop {
	background-color: var(--surface-raised);
}

:root[data-theme="cyber"] .playPauseToggleButton__play {
	background-color: var(--brand-accent);
}

/**
* checkmark.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-11 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-August-14 Checked glyph reads --text-on-status; white failed the non-text bar on 10 of 22 success fills (#1840)
*/

.checkmark__view {
	display: inline-block;
	border: var(--border-shorthand);
	border-radius: var(--radius-shell);
	padding: .5rem; /* intentional literal: fixed 2.1rem box under border-box — growing this squeezes the 1.4rem glyph */
	height: 2.1rem;
	width: 2.1rem;
	cursor: pointer;
	appearance: none;
}

.checkmark__checkbox {
	appearance: none;
	display: none;
}

.checkmark__checkmark {
	position: relative;
	display: inline-block;
	width: 1.4rem;
	height: 1.4rem;
}

.checkmark__checkmarkStart {
	position: absolute;
	left: 0;
	top: 50%;
	height: 50%;
	width: .2rem;
	background-color: var(--text-disabled);
	content: "";
	transform: translate(.2rem, -.3rem) rotate(-45deg);
	transform-origin: left bottom;
}

.checkmark__checkmarkEnd {
	position: absolute;
	left: 0;
	bottom: 0;
	height: .2rem;
	width: 100%;
	background-color: var(--text-disabled);
	content: "";
	transform: translate(.2rem, -.3rem) rotate(-45deg);
	transform-origin: left bottom;
}

.checkmark__view-checked {
	background-color: var(--status-success);

	.checkmark__checkmarkEnd {
		background-color: var(--text-on-status);
	}

	.checkmark__checkmarkStart {
		background-color: var(--text-on-status);
	}
}

/**
* scrollArea.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
* @version 2026-August-14 Chevrons read --text-on-media (#1840)
*/

/* .scrollArea__view {
    overflow: scroll;
    height: 100%;
    display: flex;
}

.scrollArea__scrollArea {
    display: block;
    scroll-behavior: smooth;
    height: fit-content;
} */

.scrollArea-horizontalView {
    display: grid;
    grid-template-areas: 'scrollArea_leftScroll scrollArea-scrollArea scrollArea_rightScroll';
    grid-template-columns: 0rem 1fr 0rem;
    grid-template-rows: 1fr;
    width: 100%;
    position: relative;
}

.scrollArea__scrollAreaContainer {
    display: flex;
    width: 100%;
    height: 100%;
    position: absolute;
    overflow: scroll;
    /* -webkit-mask-image: -webkit-linear-gradient(left, transparent, black 10%, black 90%, transparent);
    -moz-mask-image: -webkit-linear-gradient(left, transparent 1rem, black 10%, black 90%, transparent);
    mask-image: -webkit-linear-gradient(left, transparent 1rem, black 10%, black 90%, transparent); */
}

.scrollArea-scrollArea {
    /* grid-area: scrollArea-scrollArea;
    height: 100%;
    display: grid;
    grid-auto-flow: column;
    width: 100%;
    justify-content: center;
    grid-template-columns: repeat(auto-fit, 10rem); */

    /* scroll-snap-type: x mandatory;
    left: 0;
    position: absolute;
    justify-content: start;
    -webkit-mask-image: -webkit-linear-gradient(left, transparent 1rem, black 10%, black 90%, transparent);
    -moz-mask-image: -webkit-linear-gradient(left, transparent 1rem, black 10%, black 90%, transparent);
    mask-image: -webkit-linear-gradient(left, transparent 1rem, black 10%, black 90%, transparent); */
    height: 100%;
    width: 100%;
    display: flex;
    width: fit-content;
    position: absolute;
}
.scrollArea__node {
    transition: opacity 0s;
}
.scrollArea__leftScroller, .scrollArea__rightScroller {
    height: 100%;
    width: 7rem;
    display: flex;
    align-items: center;
    position: absolute;
    justify-content: center;
    pointer-events: none;
    overflow: hidden;
}
.scrollArea__leftScroller>*, .scrollArea__rightScroller>* {
    margin: auto;
    z-index: 1;
}
.scrollArea__leftScroller {
    grid-area: scrollArea_leftScroll;
    border-radius: 0 var(--radius-card) var(--radius-card) 0;
    left: 0;
}
.scrollArea__slideLeftIcon, .scrollArea__slideRightIcon {
    fill: color-mix(in srgb, var(--text-on-media) 40%, transparent);
    pointer-events: fill;
}
.scrollArea__slideLeftIcon {
    transform: scaleX(-1);
}
.scrollArea__rightScroller {
    grid-area: scrollArea_rightScroll;
    border-radius: var(--radius-card) 0 0 var(--radius-card);
    right: 0;
}
/**
* editButton.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-16 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-August-14 Pen reads --text-primary — white on the sunken surface made it invisible in every theme's light mode; commented-out hover blocks deleted (#1840)
*/

.editButton__view {
    border: var(--border-shorthand);
    border-radius: var(--radius-shell);
    padding: .5rem; /* intentional literal: fixed 2.1rem box under border-box — growing this squeezes the 1.4rem pen */
    height: 2.1rem;
    width: 2.1rem;
    background-color: var(--surface-sunken);
}

.editButton__pen {
    position: relative;
    display: inline-block;
    width: 1.4rem;
    height: 1.4rem;
}

.editButton__pen::before {
    position: absolute;
    transform: translate(-.25rem, .7rem) rotate(-45deg);
    content: "";
    border-top: .2rem solid transparent;
    border-bottom: .2rem solid transparent;
    border-right: .3rem solid var(--text-primary);
}

.editButton__pen::after {
    position: absolute;
    left: 0;
    bottom: 0;
    height: .4rem;
    width: calc(100% - .2rem);
    background-color: var(--text-primary);
    content: "";
    transform: translate(.2rem, -.5rem) rotate(-45deg);
    transform-origin: left bottom;
    border-radius: 0 var(--radius-button) var(--radius-button) 0;
}

/**
* toggleButtonBar.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
*/

.toggleButtonBar__view {
	width: fit-content;
	height: 2rem;
	display: flex;
}

.toggleButtonBar__button {
	cursor: pointer;
}

.toggleButtonBar__button:hover,
.toggleButtonBar__button:focus {
	transform: scale(1.1);
}

.toggleButtonBar__button[aria-selected="false"] {
	color: var(--text-secondary);
}

.toggleButtonBar__buttonSelector>:not(:first-child) {
	border-left: .1rem solid var(--border-default);
	padding-left: var(--pad-card);
}

.toggleButtonBar__buttonSelector>:not(:last-child) {
	margin-right: var(--gap-tile);
}

/**
* backgroundToggleBar.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-17 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type literals collapsed onto the role-token ladder; the five size rungs given symmetric vertical padding (the -smaller rung had 1px top / 0 bottom, and -larger had none at all, so the tallest rung read as the flattest)
*/

.backgroundToggleBar__view {
	position: relative;
	width: fit-content;
}

.backgroundToggleBar__buttonSelector {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
	border: var(--border-shorthand);
	border-color: var(--surface-sunken);
	background-color: var(--surface-sunken);
	border-radius: var(--radius-button);
}

.backgroundToggleBar__tab {
	position: relative;
	cursor: pointer;
	font-weight: 500;
	display: flex;
	align-items: center;
	justify-content: center;
	white-space: nowrap;
}

.backgroundToggleBar__cursor {
	position: absolute;
	z-index: 0;
	border-radius: var(--radius-button);
	box-shadow: var(--elevation-raised);
	background-color: var(--surface-card);
	/* TODO: BackgroundToggleBar.js:127-130 writes `left`/`top`/`width`/`height`
	   in px on every tab change, so the indicator animates four layout
	   properties. The FLIP form is `transform: translateX() scaleX()` with
	   `transform-origin: left`; it needs the JS rewritten. */
	transition: all var(--motion-fast) var(--ease-standard);
}

/*#region Size Modifiers*/
.backgroundToggleBar__tab-smaller {
	font-size: var(--font-size-label);
	padding: var(--pad-cell) var(--pad-dense);
}

.backgroundToggleBar__tab-small {
	font-size: var(--font-size-caption);
	padding: var(--pad-cell) var(--pad-dense);
}

.backgroundToggleBar__tab-medium {
	font-size: var(--font-size-body);
	padding: var(--pad-dense);
}

.backgroundToggleBar__tab-large {
	font-size: var(--font-size-body);
	padding: var(--pad-dense);
}

.backgroundToggleBar__tab-larger {
	font-size: var(--font-size-lead);
	padding: var(--pad-dense) var(--pad-card);
}

:root[data-viewport="phone"] {
	.backgroundToggleBar__tab {
		min-height: var(--touch-target-primary);
	}
}

/**
* expandButton.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-16 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.expandButton__view {
    border: var(--border-shorthand);
    border-radius: var(--radius-shell);
    padding: .5rem; /* intentional literal: fixed 2.1rem box under border-box — growing this squeezes the 1.4rem arrows */
    height: 2.1rem;
    width: 2.1rem;
    background-color: var(--surface-sunken);
}

.expandButton__upperArrow {
    position: relative;
    display: inline-block;
    height: 1.4rem;
}

.expandButton__upperArrow::before {
    transition: all var(--motion-fast) var(--ease-standard);
    position: absolute;
    border-radius: 50%; /* intentional literal: 50% on a non-square box (0.1rem × 45%) is an ellipse, not a stadium */
    left: 0;
    top: 50%;
    height: 45%;
    width: 0.1rem;
    background-color: var(--surface-sunken);
    content: "";
    transform: translate(.5rem, -1rem) rotate( 80deg);
}

.expandButton__upperArrow::after {
    transition: all var(--motion-fast) var(--ease-standard);
    position: absolute;
    border-radius: 50%; /* intentional literal: 50% on a non-square box (0.1rem × 45%) is an ellipse, not a stadium */
    left: 0;
    top: 50%;
    height: 45%;
    width: 0.1rem;
    background-color: var(--surface-sunken);
    content: "";
    transform: translate(0.8rem, -.8rem) rotate( 180deg);
}

.expandButton__lowerArrow {
    position: relative;
    display: inline-block;
    height: 1.4rem;
}

.expandButton__lowerArrow::before {
    transition: all var(--motion-fast) var(--ease-standard);
    position: absolute;
    border-radius: 50%; /* intentional literal: 50% on a non-square box (0.1rem × 45%) is an ellipse, not a stadium */
    left: 0;
    top: 50%;
    height: 45%;
    width: 0.1rem;
    background-color: var(--surface-sunken);
    content: "";
    transform: translate(.05rem, -.4rem) rotate(180deg);
}

.expandButton__lowerArrow::after {
    transition: all var(--motion-fast) var(--ease-standard);
    position: absolute;
    border-radius: 50%; /* intentional literal: 50% on a non-square box (0.1rem × 45%) is an ellipse, not a stadium */
    left: 0;
    top: 50%;
    height: 45%;
    width: 0.1rem;
    background-color: var(--surface-sunken);
    content: "";
    transform: translate(0.3rem, -.15rem) rotate( 80deg);
}

/* Expanded */

.expandButton-expanded {
    background-color: var(--brand-accent);
}

.expandButton__upperArrow-expanded::before {
    transform: translate(.5rem, -1rem) rotate( 180deg);
}

.expandButton__upperArrow-expanded::after {
    transform: translate(0.8rem, -.8rem) rotate( 80deg);
}

.expandButton__lowerArrow-expanded::before {
    transform: translate(.05rem, -.4rem) rotate( 80deg);
}

.expandButton__lowerArrow-expanded::after {
    transform: translate(0.3rem, -.15rem) rotate( 180deg);
}
/**
* entityTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.entityTile__view {
    cursor: pointer;
    display: grid;
    gap: var(--gap-stack);
    grid-template-columns: auto 1fr;
    align-items: center;
}

.entityTile__heading {
    text-align: left;
}
/**
* expandableEntityImage.css
* @author Jorge Pacheco <jorge.pacheco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-16 Initial Version
* @version 2026-July-16 Mobile block converted from width media query to the `data-mobile` axis (#1637)
* @version 2026-July-17 Phone rules re-gated :root[data-mobile] → :root[data-viewport="phone"] (decision 0004 phase 1, #1684)
* @version 2026-August-14 Scrim reads --surface-overlay; the paired opacity: .3 deleted so light mode renders identically and dark gets its own rung (#1840)
*/

.expandableEntityImage__view {
	cursor: pointer;
	display: block;
	cursor: pointer;
	display: flex;
	justify-content: center;
	align-items: center;
	/* The `top 0s, left 0s` exclusions are load-bearing — they keep the
	   JS-driven repositioning instant. Only the `all` segment is retimed.
	   TODO: `height`/`width` animate here too, so this is a layout animation;
	   a FLIP rewrite (transform-only) needs the driving JS changed. */
	transition: all var(--motion-slow) var(--ease-enter), top 0s, left 0s;
}

.expandableEntityImage__image {
	background-color: var(--surface-raised);
	max-width: calc(100vw - 25rem);
	max-height: calc(100vh - 20rem);
	height: 100%;
	width: 100%;
	display: flex;
}

.expandableEntityImage__background {
	position: fixed;
	width: 0;
	height: 0;
	/* The `all 0s` prefix is load-bearing: it suppresses the global transition
	   for the `width: 0 → 100vw` / `height: 0 → 100vh` snap below, leaving only
	   the scrim's colour to fade. Structure kept exactly; duration retimed. */
	transition: all 0s, background-color var(--motion-slow) var(--ease-enter);
	pointer-events: none;
	background-color: transparent;
}

.expandableEntityImage__background-expanded {
	position: fixed;
	width: 100vw;
	height: 100vh;
	top: 0;
	left: 0;
	z-index: 1;
	background-color: var(--surface-overlay);
	pointer-events: initial;
}

.expandableEntityImage__view-highlighted {
	border-color: var(--brand-accent);
}

:root[data-theme="cyber"] .expandableEntityImage__heading {
	width: 100%;
	height: 100%;
	border-radius: 0;
}

.expandableEntityImage__initialsSize {
	width: 100%;
	height: 100%;
	border-radius: var(--radius-circle);
}

/* Mobile: gated on the `data-viewport="phone"` band (JS-synced
   from PHONE_MAX_PX), never a width media query — see decisions/0004. */
:root[data-viewport="phone"] .expandableEntityImage__image {
	max-width: calc(100vw - 5rem);
}

/**
* profileImagesScrollArea.css
* @author Jorge Pacheco <jorge.pacheco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-24 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
* @version 2026-August-14 Avatar ring reads --text-on-media (#1840)
*/

.profileImagesScrollArea__view {
	position: relative;
	display: flex;
	background: rgba(0, 0, 0, 0.3);
	width: 10rem;
	height: 10rem;
	background-color: rgba(0, 0, 0, 0.3);
}

.profileImagesScrollArea__view>.profileImagesScrollArea__scrollAreaSA {
	display: flex;
	width: 100%;
	overflow-x: auto;
}

.profileImagesScrollArea__imageFrame {
	flex-shrink: 0;
	width: 8rem;
	height: 8rem;
	margin: auto var(--gap-tile);
	border-radius: var(--radius-avatar);
	border: .2rem solid var(--text-on-media);
	background-size: cover;
	background-position: center;
	cursor: pointer
}

.profileImagesScrollArea__actions {
	position: absolute;
	left: 50%;
	bottom: calc(100% + 0.5rem);
	transform: translateX(-50%);
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
	z-index: 3;
}

.profileImagesScrollArea__actions-hidden {
	display: none;
}

/* Each action is a color-coded round button: green ✓ to set/confirm, red 🗑 to delete. The
   circle is the icon's view container; its background is keyed off the icon class via :has(). */
.profileImagesScrollArea__actions .icon__view {
	width: 3.6rem;
	height: 3.6rem;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--radius-avatar);
	color: var(--text-on-brand);
	box-shadow: var(--elevation-raised);
	transition: transform var(--motion-fast) var(--ease-standard), filter var(--motion-fast) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard);
}

.profileImagesScrollArea__actions .icon__view:hover {
	transform: scale(1.08);
	filter: brightness(1.08);
	box-shadow: var(--elevation-overlay);
}

.profileImagesScrollArea__actions .icon__view:active {
	transform: scale(0.96);
}

.profileImagesScrollArea__actions .icon__view:has(.profileImagesScrollArea__actionIcon-set) {
	background: var(--status-success);
}

.profileImagesScrollArea__actions .icon__view:has(.profileImagesScrollArea__actionIcon-delete) {
	background: var(--status-danger);
}

.profileImagesScrollArea__actionIcon {
	cursor: pointer;
}

.profileImagesScrollArea__highlightedImage {
	border: .2rem solid var(--brand-accent);
}

.profileImagesScrollArea_initialsRoundHeading {
	width: 100%;
	height: 100%;
}

/**
* dropdownTextField.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-18 Initial Version
*/

.dropdownTextField__view {
	display: flex;
	align-items: center;
	box-sizing: border-box;
	min-height: 2.5rem;
	min-width: 12rem;
	position: relative;
	cursor: text;
	border-radius: var(--radius-input);
	background: var(--surface-sunken);

	.loadingPlaceholder {
		display: block;
		width: auto;
	}
}

.dropdownTextField__frame {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	border: var(--border-shorthand);
	border-radius: var(--radius-input);
	transition: clip-path .5s .2s;
}

.dropdownTextField__view:has(.dropdownTextField__input:focus-visible) {
	outline: var(--focus-ring-width) solid var(--focus-ring-color);
	outline-offset: var(--focus-ring-offset);
}

.dropdownTextField__view-disabled {
	opacity: 0.4;
	pointer-events: none;
}

.dropdownTextField__input {
	width: 100%;
	border: none;
	inset: 0;
	background: transparent;
	box-shadow: none;
	font-size: var(--font-size-body);
}

.dropdownTextField__input:not(:focus) {
	text-overflow: ellipsis;
}

.dropdownTextField__input:-webkit-autofill,
.dropdownTextField__input:-webkit-autofill:hover,
.dropdownTextField__input:-webkit-autofill:focus,
.dropdownTextField__input:-webkit-autofill:active {
	transition: background-color 5000s ease-in-out 0s;
}

.dropdownTextField__frame-open {
	transition: clip-path .5s 0s;
}

.dropdownTextField__view:has(.loadingPlaceholder) .dropdownTextField__frame {
	border: none;
}

.dropdownTextField__placeholderNode {
	position: absolute;
	left: 1rem;
	top: 50%;
	translate: 0 -50%;
	transition: top .5s 0s, left .5s 0s, font-size .5s 0s, translate .5s 0s, width .5s 0s;
	line-height: 1.1;
	max-width: calc(100% - 1.2rem);
	width: calc(100% - 3rem);
	text-align: start;
	color: var(--text-secondary);
	overflow: hidden;
	display: flex;
	align-items: baseline;
	pointer-events: none;
}

.dropdownTextField__placeholderText {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	min-width: 0;
}

.dropdownTextField__placeholderNode-shrunk {
	top: 0;
	left: 1.5rem;
	font-size: var(--font-size-label);
	width: calc(100% - 3.5rem);
	transition: top .5s .4s, left .5s .4s, font-size .5s .4s, translate .5s .4s, width .5s .4s;
}

.dropdownTextField__placeholderNodeProxy {
	opacity: 0;
	position: fixed;
	font-size: var(--font-size-label);
}

.dropdownTextField__required {
	color: var(--status-danger);
	margin-left: var(--gap-hairline);
	flex: none;
}

.dropdownTextField__option {
	width: 100%;
	cursor: pointer;
	margin: 0;
	padding: .45rem .5rem; /* intentional literal: coupled to the .dropdownTextField__scrollArea padding below so the first/last tile keeps even spacing against the panel edge */
	border-radius: var(--radius-button);
}

:not(.dropdownTextField__currentOption).dropdownTextField__option:hover {
	background-color: var(--surface-raised);
}

.dropdownTextField__scrollArea {
	height: 100%;
	padding: 1.25rem 1rem; /* intentional literal: coupled to the .dropdownTextField__option padding above so the first/last tile keeps even spacing against the panel edge */
}

.dropdownTextField__option-placeholder {
	opacity: .5;
}

.dropdownTextField__currentOption {
	background-color: var(--brand-accent);
	color: var(--text-on-brand);
}

.dropdownTextField__expandedArea {
	height: 100%;
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
	gap: var(--gap-inline);
	padding: var(--pad-dense);
	box-sizing: border-box;
}

:root[data-viewport="phone"] .dropdownTextField__placeholderNode-shrunk,
:root[data-viewport="phone"] .dropdownTextField__placeholderNodeProxy {
	font-size: var(--font-size-caption);
}

/**
* teamMemberTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-06 #1516 Former-contributor modifier + "Former" pill styling — muted-but-readable
*         (opacity kept above .6 so the tile text stays legible; the pill labels the state explicitly).
* @version 2026-July-07 #1516 Give the three italic tile text lines (displayName/role/currentTask)
*         a small inline-end pad so the slanted final glyph isn't clipped by the ellipsis
*         `overflow: hidden`.
* @version 2026-July-29 Spacing/type literals migrated onto the token contract's §Dense rungs — row chrome holds or tightens
*/

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

.teamMemberTile__view {
	display: grid;
	grid-template-columns: minmax(auto, 1fr) auto;
	cursor: pointer;
	padding: var(--pad-dense) var(--pad-row);
	color: var(--text-primary);
	align-items: center;
	width: 100%;
}

.teamMemberTile__view-selected {
	border-color: var(--brand-accent);
}

.teamMemberTile__view::after {
	opacity: 1;
}

.teamMemberTile__infoContainer {
	display: grid;
	gap: var(--gap-tight);
	overflow: hidden;
}

.teamMemberTile__displayName,
.teamMemberTile__role,
.teamMemberTile__currentTask {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	transition: none;
}

/* Opt-in detailed layout (avatar + info + live timer): leading avatar, then the
   info stack, then a right-aligned ticking timer. The default (no `showAvatar`)
   layout is untouched — these rules only apply to `-detailed`. */
.teamMemberTile__view-detailed {
	grid-template-columns: auto minmax(auto, 1fr) auto;
	gap: var(--gap-tile);
}

.teamMemberTile__currentTask {
	color: var(--text-secondary);
}

.teamMemberTile__timer {
	justify-self: end;
	font-variant-numeric: tabular-nums;
	color: var(--text-primary);
}

/* #1516 — display-name row hosts the name and the optional "Former" pill. */
.teamMemberTile__displayNameRow {
	display: flex;
	align-items: center;
	gap: var(--gap-tight);
	min-width: 0;
}

.teamMemberTile__formerBadge {
	padding: .1rem .4rem; /* intentional literal: 1px block pad on a ~9px badge; any spacing rung doubles its height */
	border: 1px solid currentColor;
	border-radius: var(--radius-pill);
	font-size: var(--font-size-label);
	line-height: 1;
	opacity: .75;
	white-space: nowrap;
	flex-shrink: 0;
}

/* Muted-but-readable: opacity stays above .6 so tile text remains legible;
 * the "Former" pill is what actually labels the state. */
.teamMemberTile__view-former {
	opacity: .75;
	font-style: italic;
}

/* Italic glyphs lean past their box's right edge; the three text lines all
 * ride `overflow: hidden` + `text-overflow: ellipsis` (see the shared rule
 * above), which clips that lean on the final character. A small inline-end
 * pad on each gives the slanted tail room. */
.teamMemberTile__view-former .teamMemberTile__displayName,
.teamMemberTile__view-former .teamMemberTile__role,
.teamMemberTile__view-former .teamMemberTile__currentTask {
	padding-inline-end: .15em; /* intentional literal: em-relative anti-clipping pad for the italic final glyph (#1516) — must scale with font-size, not the space ladder */
}

/**
 * notificationTile.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2026-05-07 Initial Version
 * @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
 * @version 2026-August-14 Unread side tab: 3px → .3rem under the units rule (#1840)
 */

.notificationTile__view {
	display: grid;
	gap: var(--gap-stack);
	padding: var(--pad-card);
	margin-bottom: var(--gap-dense);
	background: var(--surface-sunken);
}

.notificationTile__view-unread {
	border-left: .3rem solid var(--brand-primary);
}

.notificationTile__title {
	font-weight: bold;
}

.notificationTile__details {
	color: var(--text-secondary);
}

.notificationTile__status {
	color: var(--text-secondary);
	font-style: italic;
}

.notificationTile__actionsContainer {
	display: flex;
	gap: var(--gap-inline);
	justify-content: flex-end;
}

/**
* inputWithHeading.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-March-18 Initial Version
*/

.inputWithHeading__view {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
}

.inputWithHeading-heading {
	text-align: left;
}
/**
* checkboxWithLabel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.checkBoxWithLabel__view {
    display: flex;
    align-items: stretch;
    gap: var(--gap-inline);
}

.checkBoxWithLabel__label {
    text-align: left;
    cursor: pointer;
    margin-top: .1rem; /* intentional literal: 1px optical nudge — hairline, not a density step */
}
/**
* inputFieldTextArea.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-05-26 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.inputFieldTextArea__view {
  text-align: center;
  color: var(--text-primary);
  width: 100%;
  padding-top: var(--pad-dense);
}

.inputFieldTextArea__view>* {
  color: currentColor;
  background-color: transparent;
  border: none;
  width: 100%;
  text-align: center;
  -webkit-box-shadow: none;
  box-shadow: none;
  height: auto;
  margin: 0;
  padding: 0;
}

.inputFieldTextArea__heading {
  width: 100%;
  cursor: pointer;
}

.inputFieldTextArea__input::placeholder {
  color: currentColor;
}

.inputFieldTextArea__input-small {
  font-size: var(--font-size-caption);
}

.inputFieldTextArea__input-med {
  font-size: var(--font-size-lead);
}

.inputFieldTextArea__input-large {
  font-size: var(--font-size-heading);
}

.inputFieldTextArea__view-alternateColor {
  color: var(--text-on-brand);
}
/**
* calendar.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-15 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.calendar__view {
	height: 100%;
	width: 100%;
	display: grid;
	grid-template-areas: "head" "weekdays" "matrix";
	grid-template-rows: 3.0rem 2.5rem minmax(0, 1fr);
	grid-template-columns: minmax(0, 1fr);
	position: relative;
}

.calendar__header {
	grid-area: head;
	display: grid;
	grid-template-areas: "toggle prevButton month nextButton todayButton";
	grid-template-columns: 1fr 2rem auto 2rem 1fr;
	align-items: center;
}

.calendar__header>* {
	margin: auto;
}

.calendar__toggle {
	grid-area: toggle;
	padding-left: var(--pad-page);
}

.calendar__prevButton {
	grid-area: prevButton;
}

.calendar__month {
	grid-area: month;
}

.calendar__nextButton {
	grid-area: nextButton;
}

.calendar__todayButton {
	grid-area: todayButton;
	margin-right: var(--pad-page);
	background-color: var(--status-success);
}

.calendar__weekdays {
	display: grid;
	grid-template-columns: repeat(7, minmax(0, 1fr));
	grid-area: weekdays;
}

.calendar__weekdays>* {
	margin: auto;
}

.calendar__view-dayExpanded .calendar__header,
.calendar__view-dayExpanded .calendar__weekdays,
.calendar__view-dayExpanded .calendarDay__view:not(.calendarDay__view-expanded),
.calendar__view-dayExpanded .calendarWeekDay__view:not(.calendarWeekDay__view-expanded) {
	pointer-events: none;
}

/**
* calendarMonth.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-15 Initial Version
*/

.calendarMonth__view {
	grid-area: matrix;
	width: 100%;
	height: 100%;
	display: grid;
	grid-template-areas:
		"day0 day1 day2 day3 day4 day5 day6"
		"day7 day8 day9 day10 day11 day12 day13"
		"day14 day15 day16 day17 day18 day19 day20"
		"day21 day22 day23 day24 day25 day26 day27"
		"day28 day29 day30 day31 day32 day33 day34"
		"day35 day36 day37 day38 day39 day40 day41";
	grid-template-columns: repeat(7, minmax(0, 1fr));
	grid-template-rows: repeat(5, minmax(0, 1fr));
}

.calendarMonth__view-expanded {
	grid-template-rows: repeat(6, minmax(0, 1fr));
}

.calendarMonth__view-reduced {
	grid-template-rows: repeat(4, minmax(0, 1fr));
}

/**
* calendarDay.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-15 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-August-14 Cell + expanded-overlay whites tokenized; the "today" ink reads --text-on-status (#1840)
*/

.calendarDay__view {
	/* height: 0;
	width: 0; */
	padding: 0;
	opacity: 0;
	height: 100%;
	width: 100%;
}

.calendarDay__view-visible {
	opacity: 1;
	/* height: 100%;
	width: 100%; */
}

/* `transition: none`, not the old `0.001s` fake-instant: CalendarDay.js adds this
   class together with `-expandedAbsolute` below, which is declared later at the
   same specificity and therefore wins, so the expand still animates. Spelling the
   intent as `none` is behavior-identical today and survives a class-order flip. */
.calendarDay__view-expanded {
	transition: none;
	z-index: 1;
	background-color: var(--surface-raised);
	box-shadow: var(--elevation-overlay);
}

/* `all` is load-bearing here, not just house style: CalendarDay.js drives the
   collapse off a `transitionend` guarded on `ev.propertyName === 'top'`, so `top`
   must stay in the transitioned set. Only the duration changes.
   TODO: this animates `top`/`left`/`height`/`width` (written in px by the JS), so
   it is a layout animation; the FLIP rewrite needs the JS changed, and it must
   keep firing a `top` transitionend or the view never collapses. */
.calendarDay__view-expandedAbsolute {
	transition: all var(--motion-slow) var(--ease-enter);
	position: absolute;
	display: flex;
	overflow: hidden;
}

.calendarDay__expandBody {
	height: 100%;
	width: 100%;
}

.calendarDay__collapsedView {
	transition: all var(--motion-fast) var(--ease-standard);
	height: 100%;
	width: 100%;
	position: relative;
	cursor: pointer;
	background-color: var(--surface-card);
	overflow: hidden;
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
}

.calendarDay__collapsedView:hover {
	background-color: var(--surface-sunken);
}

.calendarDay__collapsedView-grey {
	background-color: var(--surface-raised);
}

.calendarDay__dayNumberArea {
	height: 3.0rem;
	width: 3.0rem;
	border-radius: var(--radius-circle);
	display: grid;
	align-items: center;
	align-content: space-around;
	justify-content: center;
	justify-self: end;
}

.calendarDay__dayNumberArea-today {
	color: var(--text-on-status);
	background-color: var(--status-success);
}

/**
* calendarDayExpandedView.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-15 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.calendarDayExpandedView__view {
	width: 100%;
	height: 100%;
	padding: var(--pad-dense);
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
	gap: var(--gap-dense);
}

.calendarDayExpandedView__closeButton {}

/**
* calendarWeek.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-15 Initial Version
*/

.calendarWeek__view {
	width: 100%;
	height: 100%;
	display: grid;
	grid-template-areas: "day0 day1 day2 day3 day4 day5 day6";
	grid-template-columns: repeat(7, minmax(0, 1fr));
	grid-template-rows: minmax(0, 1fr);
	align-items: center;
	justify-content: space-evenly;
}

/**
* calendarWeekDay.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-15 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-August-14 Expanded-overlay white tokenized; the "today" ink reads --text-on-status (#1840)
*/

.calendarWeekDay__view {
	height: 100%;
	width: 100%;
	display: flex;
	flex-direction: column;
}

.calendarWeekDay__view-verticalLine {
	border-right: .1rem solid var(--border-default);
}

/* `transition: none`, not the old `0.001s` fake-instant: CalendarWeekDay.js adds
   this class together with `-expandedAbsolute` below, which is declared later at
   the same specificity and therefore wins, so the expand still animates. In the
   one frame where only this class is present the JS has already set an inline
   `transition: none` anyway. Spelling the intent as `none` is behavior-identical
   today and survives a class-order flip. */
.calendarWeekDay__view-expanded {
	transition: none;
	z-index: 1;
	background-color: var(--surface-raised);
	box-shadow: var(--elevation-overlay);
}

/* `all` is load-bearing here, not just house style: CalendarWeekDay.js drives the
   collapse off a `transitionend` guarded on `ev.propertyName === 'top'`, so `top`
   must stay in the transitioned set. Only the duration changes.
   TODO: this animates `top`/`left`/`height`/`width` (written in px by the JS), so
   it is a layout animation; the FLIP rewrite needs the JS changed, and it must
   keep firing a `top` transitionend or the view never collapses. */
.calendarWeekDay__view-expandedAbsolute {
	transition: all var(--motion-slow) var(--ease-enter);
	position: absolute;
	display: flex;
	overflow: hidden;
}

.calendarWeekDay__expandBody {
	height: 100%;
	width: 100%;
}

.calendarWeekDay__collapsedView {
	transition: all var(--motion-fast) var(--ease-standard);
	height: 100%;
	width: 100%;
	position: relative;
	padding: 0;
	cursor: pointer;
	overflow: hidden;
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
}

.calendarWeekDay__collapsedView:hover {
	background-color: var(--surface-sunken);
}

.calendarWeekDay__collapsedView-grey {
	background-color: var(--surface-raised);
}

.calendarWeekDay__dayNumberArea {
	height: 3.0rem;
	width: 3.0rem;
	border-radius: var(--radius-circle);
	display: grid;
	align-items: center;
	align-content: space-around;
	justify-content: center;
	justify-self: end;
}

.calendarWeekDay__dayNumberArea-today {
	color: var(--text-on-status);
	background-color: var(--status-success);
}

/**
 * taskEntryTile.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2019-03-19 Initial Version
 * @version 2026-July-03 Edit-state shrink-to-form (#1221)
 * @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the edit button always (#1641)
 * @version 2026-July-29 Spacing/type literals migrated onto the token contract's §Dense rungs — row chrome holds or tightens
 */

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

.taskEntryTile__view {
	display: grid;
	grid-template-areas: 'taskEntryTile_row1Col1 taskEntryTile_col2' 'taskEntryTile_row2Col1 taskEntryTile_col2';
	grid-template-columns: 1fr auto;
	position: relative;
	align-items: center;
	padding: var(--pad-dense);
	border-radius: var(--radius-dense);
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the edit button behind it — touch devices see it always. */
@media (hover: hover) {
	.taskEntryTile__view:hover .taskEntryTile__editButton {
		opacity: 1;
	}

	.taskEntryTile__editButton {
		opacity: 0;
	}
}

/* Edit state (#1221): the tile swaps its content for the inline NewTaskPanel edit
   form, which is shrink-to-content by design. Without this cap the tile keeps
   stretching across its host column (the performance module's half-viewport
   scroll area), leaving a wide dead region to the right of the form inputs. */
.taskEntryTile__view--editing {
	width: fit-content;
	max-width: 100%;
}

.taskEntryTile__taskDescription {
	grid-area: taskEntryTile_row1Col1;
}

/* Interval total — a `getHeading` (TaskEntryTile.js:67), so it inherited
   `--font-display`. Body face + tabular figures: this is a duration column and
   the rows must line up. */
.taskEntryTile__total {
	grid-area: taskEntryTile_col2;
	font-family: var(--font-body);
	font-variant-numeric: tabular-nums;
}

.taskEntryTile__project {
	grid-area: taskEntryTile_row2Col1;
	margin-left: var(--gap-dense);
}

.taskEntryTile__editButton {
	cursor: pointer;
	position: absolute;
	top: 0;
	right: 0;
	transform: translate(50%, -50%);
}

.taskEntryTile__closeEditTaskTime {
	grid-row: 3;
	justify-self: end;
}
/**
 * dateTasksView.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2019-03-19 Initial Version 
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 */

.dateTasksView__view {
	padding: var(--pad-dense);
	display: grid;
	grid-template-areas: 'dateTasksView_date dateTasksView_total' 'dateTasksView_tileArea dateTasksView_tileArea';
}

.dateTasksView__heading {
	grid-area: dateTasksView_date;
	margin: var(--gap-dense) auto var(--gap-dense) var(--gap-stack);
}

/* Day total — tabular figures so it holds its width as intervals are logged. */
.dateTasksView__total {
	grid-area: dateTasksView_total;
	margin: var(--gap-dense) var(--gap-stack) var(--gap-dense) auto;
	font-variant-numeric: tabular-nums;
}

.dateTasksView__tileArea {
	grid-area: dateTasksView_tileArea;
	display: grid;
	gap: var(--gap-stack);

	.taskEntryTile__view {
		width: auto;
	}
}
/**
* taskTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-01 Simplify alongside TaskTile.js: 3-row grid (avatars/deadline, description/timer,
*          description/buttons); dropped the overdue pill, progress row, project, and count-down classes
* @version 2026-July-29 Spacing/type literals migrated onto the token contract's §Dense rungs — row chrome holds or tightens
*/

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

.taskTile__view {
	display: grid;
	grid-template-columns: 1fr auto;
	grid-template-areas:
		'avatars     deadline'
		'description timer'
		'project     buttons';
	/* Column gap stays at the dense rung, not --gap-tile. The wider tile gap
	   narrowed the description column 164px → 148px at the tablet band, which
	   (together with the type and line-height changes below) wrapped
	   .taskTile__description to a second line and cost 2 of 8 visible rows.
	   Caught by the rows-per-viewport guard, not by any assertion-based test. */
	gap: var(--gap-dense);
	padding: var(--pad-dense);
	color: var(--text-primary);
	cursor: pointer;
}

/* Selection highlights the border only (not the text) — mirrors ProjectTile. */
.taskTile__view-selected {
	border-color: var(--brand-accent);
}

.taskTile__view::after {
	color: var(--text-secondary);
}

.taskTile__teamMemberContainer {
	grid-area: avatars;
}

.taskTile__teamMemberContainer>* {
	height: 4.5rem;
	width: 4.5rem;
	box-shadow: 0 0 0 .25rem var(--surface-card); /* intentional literal: a spread-only avatar ring, not an elevation — an --elevation-* role would delete the overlap effect */
	border-radius: var(--radius-circle);
	transition: transform var(--motion-fast) var(--ease-standard);
}

.taskTile__teamMemberContainer>*:hover {
	transform: translateY(-.4rem);
	z-index: 1;
}

/* getChip badge — placement + on-fill styling; the gradient fill rides inline `style`. */
.taskTile__deadline {
	grid-area: deadline;
	justify-self: end;
	color: var(--Badge_On_Fill_Font_Color);
	border: none;
}

.taskTile__description {
	grid-area: description;
	/* Dense-surface type rung. The shell's `.stringNode-medium` resolves to
	   --font-size-lead (1.6rem) and body now sets --line-height-body (1.5,
	   replacing the inherited `normal` ≈1.4); on a repeating list row that
	   combination wraps the description and drops rows. A task list is a dense
	   data surface, so it takes the dense rung explicitly — see the
	   dense-data exception in knowledge-base/style/tokens.md. */
	font-size: var(--font-size-body);
	line-height: var(--line-height-tight);
}

.taskTile__project {
	grid-area: project;
	color: var(--text-secondary);
}

.taskTile__timer {
	grid-area: timer;
	justify-self: end;
	align-self: end;
	height: fit-content;
}

.taskTile__buttonContainer {
	grid-area: buttons;
	justify-self: end;
	align-self: end;
	display: flex;
	align-items: center;
	gap: var(--gap-dense);
}

.taskTile__buttonContainer>* {
	cursor: pointer;
}

/**
* teamMemberAvatars.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-01 Initial Version — reusable member-avatar row (flat + overlap variants)
*/

/* Flat row by default; the consumer's own class supplies wrap/spacing/layout. */
.teamMemberAvatars__view {
	display: flex;
}

/* Overlap variant: non-wrapping stack. Each avatar after the first slides left by
   `--avatar-overlap` (set per member-count in TeamMemberAvatars.render). */
.teamMemberAvatars__view-overlap {
	flex-wrap: nowrap;
	--avatar-overlap: 0rem;
}

.teamMemberAvatars__view-overlap>*:not(:first-child) {
	margin-left: var(--avatar-overlap);
}

/**
* taskThroughputSummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskThroughputSummary__view {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: var(--gap-inline);
	padding: var(--pad-dense) 0;
}

.taskThroughputSummary__view-hidden {
	display: none;
}

.taskThroughputSummary__heading {
	flex-basis: 100%;
	border-bottom: var(--border-shorthand);
	padding-bottom: var(--pad-cell);
}

/* Stat tiles sit in a row — tabular figures keep their widths comparable. */
.taskThroughputSummary__tile {
	flex: 0 0 auto;
	min-width: 6rem;
	font-variant-numeric: tabular-nums;
}

/**
* taskAssigneeLoad.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-June-30 Per-task rows: name | time-share progress bar | time (dropped the task-count column)
* @version 2026-July-06 #1516 Former-contributor row modifier + "Former" pill: muted-but-readable
*         (opacity kept high enough for legible text; the pill carries the explicit label).
* @version 2026-July-07 #1516 Give the italic name a small inline-end pad so the slanted
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*         final glyph isn't clipped by the ellipsis `overflow: hidden`.
*/

.taskAssigneeLoad__view {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	padding: var(--pad-card);
}

.taskAssigneeLoad__heading {
	text-align: left;
}

.taskAssigneeLoad__empty {
	opacity: .6;
}

.taskAssigneeLoad__row {
	display: grid;
	grid-template-columns: minmax(4rem, 8rem) 1fr auto;
	align-items: center;
	gap: var(--gap-tile);
}

.taskAssigneeLoad__name {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.taskAssigneeLoad__bar {
	width: 100%;
}

/* Duration column — tabular figures so the rows align down the gutter. */
.taskAssigneeLoad__time {
	text-align: right;
	white-space: nowrap;
	opacity: .7;
	font-variant-numeric: tabular-nums;
}

/* #1516 — former contributors: name cell holds the name span + a "Former" pill. */
.taskAssigneeLoad__nameCell {
	display: flex;
	align-items: center;
	gap: var(--gap-tight);
	min-width: 0;
}

.taskAssigneeLoad__formerBadge {
	padding: .1rem .4rem; /* intentional literal: 1px block pad on a ~9px badge; any spacing rung doubles its height */
	border-radius: var(--radius-pill);
	border: 1px solid currentColor;
	font-size: var(--font-size-label);
	line-height: 1;
	opacity: .75;
	white-space: nowrap;
	flex-shrink: 0;
}

/* Muted-but-readable: kept above .6 opacity so the row text stays legible,
 * and paired with the pill so the state is labelled, not just tonal. */
.taskAssigneeLoad__row--former {
	opacity: .75;
	font-style: italic;
}

/* Italic glyphs lean past their box's right edge; the name's
 * `overflow: hidden` + `text-overflow: ellipsis` clips that lean on the
 * final character. A small inline-end pad gives the slanted tail room. */
.taskAssigneeLoad__row--former .taskAssigneeLoad__name {
	padding-inline-end: .15em; /* intentional literal: em-relative anti-clipping pad for the italic final glyph (#1516) — must scale with font-size, not the space ladder */
}

/**
* taskThroughputTrend.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-30 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskThroughputTrend__view {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	min-width: 0;
}

.taskThroughputTrend__heading {
	border-bottom: var(--border-shorthand);
	padding-bottom: var(--pad-cell);
}

.taskThroughputTrend__view .graph__view {
	min-height: 14rem;
}

.taskThroughputTrend__empty {
	padding: var(--pad-card) 0;
	text-align: center;
	opacity: .6;
}

/**
* taskCycleTime.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-30 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskCycleTime__view {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	min-width: 0;
}

.taskCycleTime__heading {
	border-bottom: var(--border-shorthand);
	padding-bottom: var(--pad-cell);
}

/* Stat figure — tabular so the number doesn't shift as the value changes. */
.taskCycleTime__bigNumber .headerWithSmallHeading__header {
	font-size: var(--font-size-heading);
	line-height: 1;
	font-variant-numeric: tabular-nums;
}

/*
 * Sparkline: a bare line — shrink the graph view and hide the axis rails so only
 * the line reads. Collapse the axis grid-template down to just the canvas cell.
 */
.graph__view.taskCycleTime__sparkline {
	min-height: 3rem;
	height: 3rem;
	background-color: transparent;
	grid-template-areas: 'graph_canvas';
	grid-template-rows: 1fr;
	grid-template-columns: 1fr;
}

.taskCycleTime__sparkline .graph__yAxis,
.taskCycleTime__sparkline .graph__yAxisLabel,
.taskCycleTime__sparkline .graph__xAxis,
.taskCycleTime__sparkline .graph__xAxisLabel {
	display: none;
}

/**
* taskStatusBreakdown.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-30 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskStatusBreakdown__view {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--gap-inline);
	min-width: 0;
}

.taskStatusBreakdown__heading {
	align-self: stretch;
	border-bottom: var(--border-shorthand);
	padding-bottom: var(--pad-cell);
}

/*
 * The donut. The wrapper is unmasked and positions the ring + the centered
 * total. The conic-gradient is painted inline on the ring (style.background); a
 * radial mask cuts the ring's center into a hole so the gradient reads as a ring.
 */
.taskStatusBreakdown__chart {
	position: relative;
	width: 9rem;
	height: 9rem;
	display: flex;
	align-items: center;
	justify-content: center;
}

.taskStatusBreakdown__ring {
	position: absolute;
	inset: 0;
	border-radius: var(--radius-avatar);
	-webkit-mask: radial-gradient(circle, transparent 52%, #000 53%);
	mask: radial-gradient(circle, transparent 52%, #000 53%);
}

/* Donut centre count — tabular so the figure stays optically centred as it changes. */
.taskStatusBreakdown__total {
	position: relative;
	font-weight: 600;
	font-size: var(--font-size-lead);
	font-variant-numeric: tabular-nums;
}

.taskStatusBreakdown__legend {
	display: flex;
	flex-direction: column;
	gap: var(--gap-tight);
	align-self: stretch;
}

.taskStatusBreakdown__legendRow {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.taskStatusBreakdown__swatch {
	width: .75rem;
	height: .75rem;
	border-radius: 2px; /* intentional literal: 2px on a 7.5px swatch; the 5px --radius-dense rung would read as a circle */
	flex: 0 0 auto;
}

.taskStatusBreakdown__legendLabel {
	flex: 1 1 auto;
}

/* Legend figures — a stacked count/percent column, so they must align. */
.taskStatusBreakdown__legendCount {
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.taskStatusBreakdown__legendPercent {
	opacity: .6;
	min-width: 3ch;
	text-align: right;
	font-variant-numeric: tabular-nums;
}

.taskStatusBreakdown__empty {
	padding: var(--pad-card) 0;
	opacity: .6;
}

/**
* taskAnalyticsSection.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-30 Initial Version — full-width Analytics section: header row + 3-cell chart grid
* @version 2026-July-16 Mobile block converted from `max-width: 60rem` (= 960px!) media query to the `data-mobile` axis (#1637)
* @version 2026-July-17 Phone rules re-gated :root[data-mobile] → :root[data-viewport="phone"] (decision 0004 phase 1, #1684)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskAnalyticsSection__view {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	border: var(--border-width) solid var(--border-default);
	border-radius: var(--radius-card);
	padding: var(--pad-card);
	min-width: 0;
	min-height: 0;
}

.taskAnalyticsSection__headerRow {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--gap-inline);
	flex-wrap: wrap;
}

.taskAnalyticsSection__heading {
	color: var(--text-secondary);
}

.taskAnalyticsSection__viewAllLink {
	cursor: pointer;
	color: var(--brand-accent);
	text-decoration: underline;
}

/* Three cells: the Throughput Trend spans the first two columns (prominent),
   Cycle Time + Status Breakdown ride the remaining cells. Collapses to one
   column on a narrow viewport. */
.taskAnalyticsSection__chartGrid {
	display: grid;
	grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
	grid-auto-rows: minmax(0, auto);
	gap: var(--gap-tile);
	min-width: 0;
}

.taskAnalyticsSection__chart {
	min-width: 0;
}

.taskAnalyticsSection__chart-prominent {
	grid-row: span 2;
}

/* Mobile: single-column chart grid. Gated on the `data-viewport="phone"` band
   (JS-synced from PHONE_MAX_PX), never a width media query — see
   decisions/0004. Replaces a `max-width: 60rem` query that actually evaluated
   to 960px (media-query rem resolves against the browser-initial 16px, not our
   root rule), so the effective breakpoint tightens from 960px to 800px. */
:root[data-viewport="phone"] .taskAnalyticsSection__chartGrid {
	grid-template-columns: minmax(0, 1fr);
}

:root[data-viewport="phone"] .taskAnalyticsSection__chart-prominent {
	grid-row: auto;
}

/**
* deletedTasks.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.deletedTasks__view {
	display: flex;
	flex-direction: column;
	gap: var(--gap-dense);
	padding: var(--pad-row);
	min-width: 18rem;
}

.deletedTasks__heading {
	border-bottom: var(--border-shorthand);
	padding-bottom: var(--pad-dense);
}

.deletedTasks__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-stack);
}

.deletedTasks__empty {
	color: var(--text-secondary);
}

/**
 * timePicker.css: A modular multiuseCalendar
 *
 * @author Francisco Medina <francisco@seedburysquare.com>
 * @copyright Copyright (c) 2019 Seedbury Square LLC. All Rights Reserved.
 * @version 2020-04-11  Initial version
 * @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
 * @version 2026-August-14 Invalid-time border reads --status-danger (#1840)
 */

.timePicker__view {
	width: fit-content;
	display: grid;
	align-items: center;
	padding: var(--pad-cell);
	position: relative;
	grid-template-areas:
		'timePicker_timeInput timePicker_meridiemToggle'
		'timePicker_expandablePanel .';
	grid-template-columns: 1fr auto;
	border: var(--border-shorthand);
	border-radius: var(--radius-button);
	column-gap: var(--gap-tight);
}

.timePicker__timeInput {
	width: 5ch;
	grid-area: timePicker_timeInput;
	padding: .1rem .1rem .1rem .5rem; /* intentional literal: 1px hairline pad on a 5ch time field; the 4px left offset optically aligns it with the meridiem toggle */
}

.timePicker__meridiemPicker {
	grid-area: timePicker_meridiemToggle;
}

.timePicker__timeInput-invalidTime {
	border-color: var(--status-danger);
}

.timePicker__suggestionScrollArea {
	background: var(--surface-card);
	max-height: 10rem;
	padding: var(--pad-dense);
	margin: auto;
}

.timePicker__suggestionHeader {
	display: block;
	width: 100%;
	cursor: pointer;
	border-radius: var(--radius-button);
}

.timePicker__suggestionHeader:hover {
	background-color: var(--state-selection-highlight);
}

/*#region Size Modifiers*/
.timePicker__timeInput-smaller {
	font-size: var(--font-size-body);
}

.timePicker__timeInput-small {
	font-size: var(--font-size-lead);
}

.timePicker__timeInput-medium {
	font-size: var(--font-size-subheading);
}

.timePicker__timeInput-large {
	font-size: var(--font-size-subheading);
}

.timePicker__timeInput-larger {
	font-size: var(--font-size-heading);
}

/*#endregion Size Modifiers*/

/**
* miniCalendar.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-23 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-August-14 Phone-band day numbers one rung up — the 13.9px line box still clears the 1.8rem pill
*/

.miniCalendar__view {
	height: fit-content;
	width: fit-content;
	display: inline-grid;
	grid-template-rows: auto auto 1fr;
}

.miniCalendar__header {
	margin: 0;
	padding: 0;
	display: flex;
	align-items: center;
}

.miniCalendar__dateTimeContainer {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	gap: var(--gap-stack);
	margin-bottom: var(--gap-dense);
}

.miniCalendar__dateText {
	white-space: nowrap;
	width: 12ch;
}

.miniCalendar__timePicker {
	justify-self: end;
}

/*#region Size Modifiers*/
.miniCalendar__header-smaller {
	font-size: var(--font-size-caption);
}

.miniCalendar__header-small {
	font-size: var(--font-size-body);
}

.miniCalendar__header-medium {
	font-size: var(--font-size-lead);
}

.miniCalendar__header-large {
	font-size: var(--font-size-subheading);
}

.miniCalendar__header-larger {
	font-size: var(--font-size-subheading);
}

.miniCalendar__dateText-smaller {
	font-size: var(--font-size-body);
}

.miniCalendar__dateText-small {
	font-size: var(--font-size-lead);
}

.miniCalendar__dateText-medium {
	font-size: var(--font-size-subheading);
}

.miniCalendar__dateText-large {
	font-size: var(--font-size-subheading);
}

.miniCalendar__dateText-larger {
	font-size: var(--font-size-heading);
}

.miniCalendar__weekdays-smaller {
	font-size: var(--font-size-label);
}

.miniCalendar__weekdays-small {
	font-size: var(--font-size-label);
}

.miniCalendar__weekdays-medium {
	font-size: var(--font-size-caption);
}

.miniCalendar__weekdays-large {
	font-size: var(--font-size-body);
}

.miniCalendar__weekdays-larger {
	font-size: var(--font-size-lead);
}

/*#endregion Size Modifiers*/

.miniCalendar__calendarContainer {
	height: 100%;
	width: 100%;
	padding: var(--pad-card);
	display: grid;
	grid-template-areas: 'miniCalendar_head' 'miniCalendar_weekdays' 'miniCalendar_matrix';
	grid-template-rows: auto auto 1fr;
	border-radius: var(--radius-card);
}

.miniCalendar__matrix {
	width: 100%;
	display: grid;
	grid-template-areas: 'miniCalendar_day0 miniCalendar_day1 miniCalendar_day2 miniCalendar_day3 miniCalendar_day4 miniCalendar_day5 miniCalendar_day6' 'miniCalendar_day7 miniCalendar_day8 miniCalendar_day9 miniCalendar_day10 miniCalendar_day11 miniCalendar_day12 miniCalendar_day13' 'miniCalendar_day14 miniCalendar_day15 miniCalendar_day16 miniCalendar_day17 miniCalendar_day18 miniCalendar_day19 miniCalendar_day20' 'miniCalendar_day21 miniCalendar_day22 miniCalendar_day23 miniCalendar_day24 miniCalendar_day25 miniCalendar_day26 miniCalendar_day27' 'miniCalendar_day28 miniCalendar_day29 miniCalendar_day30 miniCalendar_day31 miniCalendar_day32 miniCalendar_day33 miniCalendar_day34' 'miniCalendar_day35 miniCalendar_day36 miniCalendar_day37 miniCalendar_day38 miniCalendar_day39 miniCalendar_day40 miniCalendar_day41';
	grid-template-columns: repeat(7, 1fr);
	grid-template-rows: repeat(5, 1fr);
	gap: var(--gap-dense);
}

.miniCalendar__matrix-expanded {
	grid-template-rows: repeat(6, 1fr);
}

.miniCalendar__matrix-reduced {
	grid-template-rows: repeat(4, 1fr);
}

.miniCalendar__day-view {
	display: flex;
	height: 0;
	width: 0;
	padding: 0;
	opacity: 0;
	border-radius: var(--radius-dense);
	align-items: center;
}

.miniCalendar__day-view-visible {
	opacity: 1;
	height: 100%;
	width: 100%;
	cursor: pointer;
}

/* Header */

.miniCalendar__header-container {
	/* grid-area: miniCalendar_head; */
	display: grid;
	grid-template-areas: 'miniCalendar_monthNav miniCalendar_yearNav miniCalendar_todayButton';
	grid-template-columns: auto 1fr;
	align-content: center;
	justify-content: center;
}

.miniCalendar__header-container>* {
	/* font-size: .8rem; */
	margin: auto;
}

.miniCalendar__header-container-small {
	font-size: var(--font-size-label);
}

.miniCalendar__header-container-medium {
	font-size: var(--font-size-caption);
}

.miniCalendar__header-container-large {
	font-size: var(--font-size-subheading);
}

.miniCalendar__header-navButtonSet {
	display: grid;
	grid-template-columns: auto 1fr auto;
	justify-content: space-evenly;
	gap: var(--gap-inline);
}

.miniCalendar__header-navButtonSet>* {
	margin: auto;
	font-size: inherit;
}

.miniCalendar__header-navButtonSet-small {
	font-size: var(--font-size-label);
}

.miniCalendar__header-navButtonSet-medium {
	font-size: var(--font-size-caption);
}

.miniCalendar__header-navButtonSet-large {
	font-size: var(--font-size-subheading);
}

.miniCalendar__header-monthNav {
	/* grid-area: miniCalendar_monthNav; */
}

.miniCalendar__header-yearNav {
	/* grid-area: miniCalendar_yearNav; */
}

.miniCalendar__header-todayButton {
	/* grid-area: miniCalendar_todayButton; */
	margin: auto var(--gap-dense) auto auto;
}

.miniCalendar__header-todayButton-smaller {
	font-size: var(--font-size-label);
}

.miniCalendar__header-todayButton-small {
	font-size: var(--font-size-caption);
}

.miniCalendar__header-todayButton-medium {
	font-size: var(--font-size-lead);
}

.miniCalendar__header-todayButton-large {
	font-size: var(--font-size-heading);
}

.miniCalendar__header-todayButton-larger {
	font-size: var(--font-size-heading);
}

.miniCalendar__day-dayNumberArea {
	height: 1.8rem;
	width: 1.8rem;
	border-radius: var(--radius-circle);
	font-size: var(--font-size-caption);
	margin: auto;
	text-align: center;
	line-height: var(--line-height-tight);
	display: grid;
	justify-content: center;
	align-items: center;
}

.miniCalendar__day-dayNumberArea-small {
	font-size: var(--font-size-caption);
	line-height: var(--line-height-tight);
	width: 2rem;
	height: 2rem;
}

.miniCalendar__day-dayNumberArea-medium {
	font-size: var(--font-size-lead);
	height: 2.5rem;
	width: 2.5rem;
	line-height: 1.85rem;
}

.miniCalendar__day-dayNumberArea-large {
	font-size: var(--font-size-heading);
	width: 3.7rem;
	height: 3.7rem;
	line-height: 3.06rem;
}

.miniCalendar__day-dayNumberArea:hover {
	border: .1rem solid currentColor;
}

.miniCalendar__day-dayNumberArea-selectedDay {
	color: var(--text-on-brand);
	background: var(--brand-accent);
}

.miniCalendar__day-dayNumberArea-today {
	border: .1rem solid var(--brand-accent);
}

.miniCalendar__weekdays {
	/* grid-area: miniCalendar_weekdays; */
	margin: var(--gap-tight) 0;
	display: grid;
	grid-template-columns: repeat(7, 1fr);
}

.miniCalendar__weekdays>* {
	/* font-size: .8rem; */
	color: var(--text-primary);
	margin: auto;
	font-size: inherit;
}

/* Phone band: the base rung measures 9.95px at 390px inside a 1.8rem (14.9px)
   pill. One rung up is 11.6px text in a 13.9px line box — still inside the pill,
   so the disc geometry is untouched. The -medium/-large size modifiers already
   read larger rungs. */
:root[data-viewport="phone"] .miniCalendar__day-dayNumberArea {
	font-size: var(--font-size-body);
}

/**
 * datePicker.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2020-04-09 Initial Version 
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 */

.datePicker__view {
    position: relative;
    cursor: pointer;
}

.datePicker__miniCalendar {
    /* No `top` override — would hijack position-area's implicit inset. Anchor gap is the shared margin-block on __view. */
    background: var(--surface-page);
}

/* datePickerWithInput */

.datePickerWithInput__view {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    width: fit-content;
    justify-content: space-between;
    gap: var(--gap-stack);
}
/**
* headerWithSmallHeading.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.headerWithSmallHeading__view {
	display: grid;
	grid-template-rows: repeat(2, auto);
	grid-template-columns: 1fr;
	justify-content: start;
	height: fit-content;
	width: fit-content;
	gap: var(--gap-tight);
}

.headerWithSmallHeading__head {
	color: var(--text-primary);
	font-size: var(--font-size-label);
}
/**
* projectInfo.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.projectInfo__view {
	padding: var(--pad-card);
	display: grid;
	grid-template-areas: 'projectInfo__client projectInfo__projectDescription' 'projectInfo__compensation projectInfo__budget' 'projectInfo__timeLimit projectInfo__taxes' 'projectInfo__deadLine .';
	grid-gap: 3rem;
}

.projectInfo__client,
.projectInfo__projectDescription,
.projectInfo__budget,
.projectInfo__compensation,
.projectInfo__timeLimit,
.projectInfo__tax {
	border: var(--border-shorthand);
	border-radius: var(--radius-button);
	padding: var(--pad-card);
}

/* The three money tiles — tabular figures so the amounts read as a column
   across the grid rather than three independently-drifting strings. */
.projectInfo__budget,
.projectInfo__compensation,
.projectInfo__tax {
	font-variant-numeric: tabular-nums;
}

.projectInfo__client {
	grid-area: projectInfo__client;
	height: 100%;
	width: 100%;
}

.projectInfo__clientName {
	color: var(--brand-accent);
	cursor: pointer;
	width: fit-content;
}

.projectInfo__projectDescription {
	grid-area: projectInfo__projectDescription;
	height: 100%;
	width: 100%;
}

.projectInfo__budget {
	grid-area: projectInfo__budget;
	height: 100%;
	width: 100%;
}

.projectInfo__compensation {
	grid-area: projectInfo__compensation;
	height: 100%;
	width: 100%;
}

.projectInfo__timeLimit {
	grid-area: projectInfo__timeLimit;
	height: 100%;
	width: 100%;
}

.projectInfo__deadLine {
	grid-area: projectInfo__deadLine;
	height: 100%;
	width: 100%;
}

.projectInfo__tax {
	grid-area: projectInfo__taxes;
	height: 100%;
	width: 100%;
}

.projectInfo__taxTile {
	display: flex;
}

.projectInfo__innerTaxContainer {}

/**
 * invoice.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2020-04-17 Initial Version 
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 * @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
 */

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

/* NOT converted below: the table half of this file (.invoice__Table-layout,
   .invoice__table__header*, .invoice__mainTable*, .invoice__signatureArea*) is dead —
   Invoice.js delegates the table to InvoiceTable, whose own CSS owns those rules.
   Skipped per the dead-rule ruling; deletion rides its own triplet. */
.invoice__view {
    height: calc(100dvh - 15rem);
    width: 100%;
    background-color: var(--surface-card);
    display: grid;
    padding: var(--pad-page) 5rem; /* intentional literal: the 5rem inline gutter is the printed-document side margin; no role exists above 24px */
    gap: var(--gap-section);
    grid-template-rows: repeat(3, auto) 1fr;
}

.invoice__addressLogo {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.invoice__mainHeader {
    font-size: var(--font-size-display);
    color: var(--brand-accent);
}

.invoice__mainLogo {
    height: 8rem;
    width: 8rem;
    border: .3rem solid var(--brand-primary);
    /* box-shadow: var(--elevation-surround); */
    background-color: transparent;
    /* background-color: var(--surface-raised); */
    border-radius: var(--radius-avatar);
    -webkit-border-radius: var(--radius-avatar);
    -moz-border-radius: var(--radius-avatar);
}

.invoice__invoiceNumberDate {
    display: flex;
    justify-content: space-between;
    padding: var(--pad-dense);
    /* background-color: rgb(33, 51, 117); */
    background: var(--brand-accent);
    color: white;
}

.invoice__addressBar {
    height: auto;
    display: flex;
}

.invoice__addressBlock {
    width: 100%;
}

.invoice__addressBlock__heading {
    /* color: rgb(118, 145, 166); */
    color: var(--brand-accent);
    /* Was `Helvetica, sans-serif` + `font-weight: 100`: a hardcoded face that
       ignored the theme entirely, and a weight no declared @font-face provides
       (every face here starts at 400, so 100 already rendered as 400). */
    font-family: var(--font-body);
    font-weight: var(--font-weight-body);
    font-size: var(--font-size-body);
    padding: var(--pad-dense);
}

.invoice__addressBlock__content {
    display: flex;
    padding: var(--pad-dense);
}

.invoice__Table-layout {
    display: grid;
    grid-template-columns: 12rem 1fr 10rem 10rem 10rem;
}

/* Table Header */

.invoice__table__header {
    /* column-gap: .1rem; */
}

.invoice__table__header__heading {
    /* background-color: rgb(33, 51, 117); */
    background: var(--brand-accent);
    color: white;
    width: 100%;
    height: fit-content;
    padding: 1rem 1.5rem;
    font-family: Helvetica, sans-serif;
    font-weight: 100;
    border-right: var(--border-shorthand);
    border-color: white;
}

.invoice__table__header__heading:last-child {
    border: none;
}

.invoice__table {
    display: grid;
    height: fit-content;
    gap: var(--gap-section)
}

/* Main Table */

.invoice__mainTable {
    display: grid;
    height: fit-content;
}

.invoice__mainTable__row {}

.invoice__mainTable__row-cell {
    width: 100%;
    padding: 1rem .5rem;
    font-weight: 100;
    border-right: var(--border-shorthand);
    border-bottom: var(--border-shorthand);
}

.invoice__mainTable__row-cell:first-child {
    border-left: var(--border-shorthand);
}

.invoice__mainTable__row-cell-alignLeft {
    text-align: left;
}

/* Totals */

.invoice__totalsTable {
    width: 50%;
    margin: var(--gap-stack) 0 auto auto;
}

.invoice__totalsTable__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--pad-dense);
}

/* Both halves of a totals row are built with `getHeading` (Invoice.js:71-72),
   which stamps `.heading` and therefore `font-family: var(--font-display)`
   (baseElements.css:277) — so an invoice total rendered in Audiowide on
   futuristic and a serif on elegant/retro. Money belongs on the body face:
   these two rules pin it back, and the value gets tabular figures so the
   column aligns. Both are single-class selectors like `.heading`, and
   invoice.css imports after baseElements.css (styleSheet.css:15 vs :66), so
   they win the equal-specificity tie on source order. */
.invoice__totalsTable__row__heading {
    color: var(--brand-accent);
    /* color: rgb(118, 145, 166); */
    /* Was `Helvetica, sans-serif` + `font-weight: 100` — see the address block above. */
    font-family: var(--font-body);
    font-weight: var(--font-weight-body);
    font-size: var(--font-size-body);
}

.invoice__totalsTable__row__value {
    font-family: var(--font-body);
    font-variant-numeric: tabular-nums;
}

/* Special Text */

.invoice__specialText {
    text-align: justify;
}

/* Signature Area */

.invoice__signatureArea {
    display: grid;
    grid-template-areas: 'invoice__signatureArea_line invoice__signatureArea_line''. invoice__signatureArea_name''. invoice__signatureArea_role';
    grid-template-rows: repeat(3, auto);
    grid-template-columns: 5rem 1fr;
    width: 50%;
    column-gap: 1.5rem;
}

.invoice__signatureArea__signatureLine {
    grid-area: invoice__signatureArea_line;
    display: grid;
    grid-template-columns: auto 1fr;
    gap: .5rem;
    margin-bottom: .5rem;
}

.invoice__signatureArea_name {
    grid-area: invoice__signatureArea_name;
}

.invoice__signatureArea_role {
    grid-area: invoice__signatureArea_role;
}
/**
* invoiceTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.invoiceTile__view {
    display: grid;
    border: var(--border-shorthand);
    border-radius: var(--radius-button);
    padding: var(--pad-row);
    cursor: pointer;
}

.invoiceTile__statusChip {
    justify-self: start;
    padding: var(--pad-dense);
    border-radius: var(--radius-pill);
    font-size: var(--font-size-caption);
    background: var(--surface-sunken);
    color: var(--text-secondary);
}

.invoiceTile__statusChip-paid {
    background: var(--brand-primary);
    color: var(--text-on-brand);
}
/**
 * invoiceTable.css
 * @author Jorge Pacheco <jorge.pacheco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2021-05-04 Initial Version 
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 */

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

/* NOT converted below: the document-chrome half of this file (.invoiceTable__addressLogo,
   __mainHeader, __mainLogo, __invoiceNumberDate, __addressBar, __addressBlock*, __totalsTable*,
   __specialText, __signatureArea*) is dead — InvoiceTable renders only the table; Invoice owns
   the chrome. The copy-paste fingerprint is the `grid-area: invoice__signatureArea_*` below,
   still carrying the other file's prefix. Skipped per the dead-rule ruling. */
.invoiceTable__view {}

.invoiceTable__addressLogo {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.invoiceTable__mainHeader {
    font-size: 4rem;
    color: var(--brand-accent);
}

.invoiceTable__mainLogo {
    height: 8rem;
    width: 8rem;
    border: .3rem solid var(--brand-primary);
    /* box-shadow: var(--elevation-surround); */
    background-color: var(--surface-raised);
    border-radius: var(--radius-avatar);
    -webkit-border-radius: var(--radius-avatar);
    -moz-border-radius: var(--radius-avatar);
}

.invoiceTable__invoiceNumberDate {
    display: flex;
    justify-content: space-between;
    padding: .5rem;
    /* background-color: rgb(33, 51, 117); */
    background: var(--brand-accent);
    color: white;
}

.invoiceTable__addressBar {
    height: auto;
    display: flex;
}

.invoiceTable__addressBlock {
    width: 100%;
}

.invoiceTable__addressBlock__heading {
    /* color: rgb(118, 145, 166); */
    color: var(--brand-accent);
    font-family: Helvetica, sans-serif;
    font-weight: 100;
    font-size: 1.4rem;
    padding: .5rem;
}

.invoiceTable__addressBlock__content {
    display: flex;
    padding: .5rem;
}

.invoiceTable__Heading {
    text-align: left;
    color: var(--brand-accent);
    margin-bottom: var(--gap-dense);
}

.invoiceTable__Table-layout {
    display: grid;
    grid-template-columns: 12rem 1fr 10rem 10rem 10rem;
}

/* Table Header */

.invoiceTable__table__header {
    /* column-gap: .1rem; */
}

.invoiceTable__table__header__heading {
    /* background-color: rgb(33, 51, 117); */
    background: var(--brand-accent);
    color: white;
    width: 100%;
    height: fit-content;
    padding: var(--pad-dense) var(--pad-card);
    /* Was `Helvetica, sans-serif` + `font-weight: 100` — the same theme-deaf
       pin as the invoice address and totals headings, one file over, and this
       one is live (InvoiceTable.js stamps the class). The weight was already
       inert: no declared @font-face provides a 100 weight, so it rendered 400. */
    font-family: var(--font-body);
    font-weight: var(--font-weight-body);
    border-right: var(--border-shorthand);
    border-color: white;
}

.invoiceTable__table__header__heading:last-child {
    border: none;
}

.invoiceTable__table {
    display: grid;
    height: fit-content;
}

/* Main Table */

.invoiceTable__mainTable {
    display: grid;
    height: fit-content;
}

.invoiceTable__mainTable__row {}

/* Every cell in the line-item table is built with `getHeading`
   (InvoiceTable.js:65-69), which stamps `.heading` and therefore
   `font-family: var(--font-display)` (baseElements.css:277) — so the rate and
   total columns rendered in Audiowide on futuristic and a serif on
   elegant/retro. Pinned back to the body face, with tabular figures so the
   money columns align. Applied to the whole row rather than the numeric
   columns only: the description column has the same display-face problem, and
   `tabular-nums` is inert on text. Wins the equal-specificity tie with
   `.heading` on source order (styleSheet.css:15 vs :68). */
.invoiceTable__mainTable__row-cell {
    width: 100%;
    padding: var(--pad-dense);
    font-family: var(--font-body);
    font-variant-numeric: tabular-nums;
    /* Was `font-weight: 100` — no declared @font-face provides a 100 weight
       (every face starts at 400), so it already rendered as 400. */
    font-weight: var(--font-weight-body);
    border-right: var(--border-shorthand);
    border-bottom: var(--border-shorthand);
}

.invoiceTable__mainTable__row-cell:first-child {
    border-left: var(--border-shorthand);
}

.invoiceTable__mainTable__row-cell-alignLeft {
    text-align: left;
}

/* Totals */

.invoiceTable__totalsTable {
    width: 50%;
    margin: 1rem 0 auto auto;
}

.invoiceTable__totalsTable__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .5rem;
}

.invoiceTable__totalsTable__row__heading {
    color: var(--brand-accent);
    /* color: rgb(118, 145, 166); */
    font-family: Helvetica, sans-serif;
    font-weight: 100;
    font-size: 1.4rem;
}

.invoiceTable__totalsTable__row__value {}

/* Special Text */

.invoiceTable__specialText {
    text-align: justify;
}

/* Signature Area */

.invoiceTable__signatureArea {
    display: grid;
    grid-template-areas: 'invoice__signatureArea_line invoice__signatureArea_line''. invoice__signatureArea_name''. invoice__signatureArea_role';
    grid-template-rows: repeat(3, auto);
    grid-template-columns: 5rem 1fr;
    width: 50%;
    column-gap: 1.5rem;
}

.invoiceTable__signatureArea__signatureLine {
    grid-area: invoice__signatureArea_line;
    display: grid;
    grid-template-columns: auto 1fr;
    gap: .5rem;
    margin-bottom: .5rem;
}

.invoiceTable__signatureArea_name {
    grid-area: invoice__signatureArea_name;
}

.invoiceTable__signatureArea_role {
    grid-area: invoice__signatureArea_role;
}
/**
* invoiceCartIcon.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-21 Initial Version (invoice payer flow)
*/

.invoiceCartIcon__view {
	display: flex;
	align-items: center;
	justify-content: center;
}

.invoiceCartIcon__view-hidden {
	display: none;
}

.invoiceCartIcon__icon {
	height: 2.5rem;
	color: var(--text-secondary);
}

.invoiceCartIcon__list {
	display: grid;
	gap: var(--gap-stack);
	align-content: start;
	padding: var(--pad-page);
}

.invoiceCartIcon__listHeading {
	margin-bottom: var(--gap-stack);
}

.invoiceCartIcon__entry {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	gap: var(--gap-inline);
	padding: var(--pad-card);
	border-radius: var(--radius-button);
	background: var(--surface-sunken);
}

.invoiceCartIcon__entryInfo {
	display: grid;
	gap: var(--gap-dense);
}

.invoiceCartIcon__entrySeller {
	font-weight: bold;
}

.invoiceCartIcon__entryDate {
	color: var(--text-secondary);
}

.invoiceCartIcon__entryActions {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

:root[data-viewport="phone"] .invoiceCartIcon__view .icon__view {
	min-height: var(--touch-target-primary);
	min-width: var(--touch-target-primary);
}

/**
* registerPaymentDialog.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-21 Initial Version (invoice payer flow)
*/

.registerPaymentDialog__view {
	display: grid;
	gap: var(--gap-stack);
	padding: var(--pad-card);
	max-width: 40rem;
}

.registerPaymentDialog__remaining {
	color: var(--text-secondary);
}

.registerPaymentDialog__buttons {
	display: flex;
	justify-content: flex-end;
	gap: var(--gap-inline);
}

.registerPaymentDialog__amendButton {
	justify-self: start;
}

:root[data-viewport="phone"] .registerPaymentDialog__amendButton {
	min-height: var(--touch-target-primary);
}

/**
* clientClaimChooser.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-21 Initial Version (invoice payer flow)
*/

.clientClaimChooser__view {
	display: grid;
	gap: var(--gap-stack);
	padding: var(--pad-card);
	max-width: 46rem;
}

.clientClaimChooser__copy {
	color: var(--text-secondary);
}

.clientClaimChooser__entityPicker {
	display: grid;
	gap: var(--gap-dense);
}

.clientClaimChooser__entityPickerLabel {
	color: var(--text-secondary);
}

.clientClaimChooser__entityList {
	display: grid;
	gap: var(--gap-dense);
	max-height: 24rem;
}

.clientClaimChooser__entityOption {
	padding: var(--pad-row);
	border: var(--border-shorthand);
	border-radius: var(--radius-button);
	cursor: pointer;
}

.clientClaimChooser__entityOption:hover {
	background: var(--surface-hover);
}

:root[data-viewport="phone"] .clientClaimChooser__entityOption,
:root[data-viewport="phone"] .clientClaimChooser__rejectButton {
	min-height: var(--touch-target-primary);
}

/**
* receivedInvoiceRow.css — the received-invoices row rules, moved with the row
* markup from receivedInvoices.css (#1973/#1979). Selectors keep the
* `receivedInvoicesView__*` vocabulary the journey tests pin. The two
* `__statusChip` selectors have a SECOND consumer: the container's detail
* overlay (ReceivedInvoicesView#renderInvoiceDetail) renders the same chip —
* renaming or deleting them here silently unstyles the overlay until the
* deferred shared-chip builder lands.
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-22 Initial Version (#1973/#1979)
*/

.receivedInvoicesView__row {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	gap: var(--gap-inline);
	padding: var(--pad-dense);
	border: var(--border-shorthand);
	border-radius: var(--radius-button);
	cursor: pointer;
}

.receivedInvoicesView__rowInfo {
	display: grid;
	gap: var(--gap-dense);
}

.receivedInvoicesView__rowSeller {
	font-weight: bold;
}

.receivedInvoicesView__rowDate {
	color: var(--text-secondary);
}

.receivedInvoicesView__rowFigures {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.receivedInvoicesView__statusChip {
	padding: var(--pad-dense);
	border-radius: var(--radius-pill);
	font-size: var(--font-size-caption);
	background: var(--surface-sunken);
	color: var(--text-secondary);
}

.receivedInvoicesView__statusChip-paid {
	background: var(--brand-primary);
	color: var(--text-on-brand);
}

:root[data-viewport="phone"] .receivedInvoicesView__row {
	min-height: var(--touch-target-primary);
}

/**
* dropdown.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-03-04 Initial Version
* @version 2026-Jun-26 MMR — Add `dropdown__option-checked` rule for multi-select checked tiles.
* @version 2026-Jun-26 MMR — Move the heading-area padding from `dropdown__view` to `dropdown__headingArea` so the full bordered area is part of the focusable click target.
* @version 2026-Jun-26 MMR — Replace the option-tile `.5rem 0` margin with vertical padding so the inter-tile strip is clickable; bump scrollArea vertical padding to compensate so first/last tile positions stay put.
* @version 2026-Jun-26 MMR — Multi-mode visual cleanup: drop the left border on checked tiles; reserve the ✓ column on every option to prevent layout shift; subtler cursor highlight (lighter_grey) so it isn't mistaken for "selected".
* @version 2026-Jun-26 MMR — Searchbar breathing room: move the 1rem top gap from the searchbar's `margin-top` (which collapsed through the parent into the panel border) to a `padding-top` on `expandedArea`, scoped via `:has(> .dropdown__searchbar)` so non-search dropdowns are untouched.
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.dropdown__view {
	display: flex;
	align-items: center;
	box-sizing: border-box;
	min-height: 2.5rem;
	min-width: 12rem;
	width: fit-content;
	position: relative;
	cursor: pointer;
	border-radius: var(--radius-input);
	background: var(--surface-sunken);

	.loadingPlaceholder {
		display: block;
		width: auto;
	}
}

.dropdown__frame {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	border: var(--border-shorthand);
	border-radius: var(--radius-input);
	transition: clip-path .5s .2s;
}

.dropdown__frame-open {
	transition: clip-path .5s 0s;
}

.dropdown__view:has(.loadingPlaceholder) .dropdown__frame {
	border: none;
}

.dropdown__placeholderNode {
	position: absolute;
	left: 1rem;
	top: 50%;
	translate: 0 -50%;
	transition: top .5s 0s, left .5s 0s, font-size .5s 0s, translate .5s 0s, width .5s 0s;
	line-height: 1.1;
	max-width: calc(100% - 1.2rem);
	width: calc(100% - 3rem);
	text-align: start;
	color: var(--text-secondary);
	overflow: hidden;
	display: flex;
	align-items: baseline;
	pointer-events: none;
}

.dropdown__placeholderText {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	min-width: 0;
}

.dropdown__placeholderNode-shrunk {
	top: 0;
	left: 1.5rem;
	font-size: var(--font-size-label);
	width: calc(100% - 3.5rem);
	transition: top .5s .4s, left .5s .4s, font-size .5s .4s, translate .5s .4s, width .5s .4s;
}

.dropdown__placeholderNodeProxy {
	opacity: 0;
	position: fixed;
	font-size: var(--font-size-label);
}

.dropdown__required {
	color: var(--status-danger);
	margin-left: var(--gap-hairline);
	flex: none;
}

.dropdown__option {
	width: 100%;
	cursor: pointer;
	margin: 0;
	padding: .45rem .5rem; /* intentional literal: coupled to the .dropdown__scrollArea padding below (first/last-tile invariant) and kept byte-parallel with endlessDropdown.css's .endlessDropdown__option — see the @version note; +78% vertical on an unbounded option list is exactly what §Dense forbids */
	border-radius: var(--radius-button);
}

:not(.dropdown__currentOption).dropdown__option:hover {
	background-color: var(--surface-raised);
}

.dropdown__headingArea {
	width: 100%;
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
	padding: 0 var(--pad-card);
	box-sizing: border-box;
}

.dropdown__headingArea-disabled {
	opacity: .5;
	cursor: not-allowed;
	pointer-events: none;
}

.dropdown__placeholder {
	min-width: 0;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	text-align: start;
	font-size: var(--font-size-body);
}

.dropdown__scrollArea {
	height: 100%;
	padding: 1.25rem 1rem; /* intentional literal: coupled to the .dropdown__option padding above — converting one half breaks the documented first/last-tile invariant */
}

.dropdown__option-placeholder {
	opacity: .5;
}

.dropdown__dropdownArrow {
	/* width: 0;
	height: 0;
	border-top: .5rem solid transparent;
	border-bottom: .5rem solid transparent;
	border-left: 1rem solid var(--text-primary);
	margin-left: .5rem;
	margin-top: .1rem; */
	cursor: pointer;
}

.dropdown__dropdownArrow-expanded {
	transform: rotate(90deg);
}

.dropdown__dropdown {
	display: none;
	width: 100%;
}

.dropdown__currentOption {
	background-color: var(--brand-accent);
	color: var(--text-on-brand);
}

/* Multi-mode only — scope by the native `<select multiple>` attribute so single-mode dropdowns are untouched. */

/* Reserve the ✓ column on every option so checking the first doesn't shift text right; transparent glyph holds the space, painted glyph appears on `-checked`. */
.dropdown__view:has(select[multiple]) .dropdown__option::before {
	content: '✓ ';
	color: transparent;
	font-weight: bold;
}

.dropdown__view:has(select[multiple]) .dropdown__option-checked::before {
	color: var(--brand-accent);
}

/* Keyboard cursor in multi mode is a faint highlight — the ✓ already conveys selection, and the full color flip used in single mode reads as "selected", which is misleading when both checked + cursor land on different tiles. */
.dropdown__view:has(select[multiple]) .dropdown__currentOption {
	background-color: var(--surface-hover);
	color: inherit;
}

.dropdown__expandedArea {
	height: 100%;
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
	gap: var(--gap-inline);
	padding: var(--pad-dense);
	box-sizing: border-box;
}

/* Search-enabled dropdowns: give expandedArea its own top padding so the searchbar's `margin-top` can't collapse through the parent and land flush against the panel's expand-area padding. */
.dropdown__expandedArea:has(> .dropdown__searchbar) {
	padding-top: var(--pad-row);
}

.dropdown__searchbar {
	margin: 0 var(--gap-stack);
}


:root[data-viewport="phone"] {

	.dropdown__view,
	.dropdown__option-placeholder,
	.dropdown__option {
		min-height: var(--touch-target-primary);
	}

	.dropdown__placeholderNode-shrunk,
	.dropdown__placeholderNodeProxy {
		font-size: var(--font-size-caption);
	}
}

/**
* endlessDropdown.css
* @author Louis Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-Jul-13 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.endlessDropdown__view {
	display: flex;
	align-items: center;
	box-sizing: border-box;
	min-height: 2.5rem;
	min-width: 12rem;
	width: fit-content;
	position: relative;
	cursor: pointer;
	border-radius: var(--radius-input);
	background: var(--surface-sunken);
}

.endlessDropdown__frame {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	border: var(--border-shorthand);
	border-radius: var(--radius-input);
	transition: clip-path .5s .2s;
}

.endlessDropdown__frame-open {
	transition: clip-path .5s 0s;
}

.endlessDropdown__placeholderNode {
	position: absolute;
	left: 1rem;
	top: 50%;
	translate: 0 -50%;
	transition: top .5s 0s, left .5s 0s, font-size .5s 0s, translate .5s 0s, width .5s 0s;
	line-height: 1.1;
	max-width: calc(100% - 1.2rem);
	width: calc(100% - 3rem);
	text-align: start;
	color: var(--text-secondary);
	overflow: hidden;
	display: flex;
	align-items: baseline;
	pointer-events: none;
}

.endlessDropdown__placeholderText {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	min-width: 0;
}

.endlessDropdown__placeholderNode-shrunk {
	top: 0;
	left: 1.5rem;
	font-size: var(--font-size-label);
	width: calc(100% - 3.5rem);
	transition: top .5s .4s, left .5s .4s, font-size .5s .4s, translate .5s .4s, width .5s .4s;
}

.endlessDropdown__placeholderNodeProxy {
	opacity: 0;
	position: fixed;
	font-size: var(--font-size-label);
}

.endlessDropdown__required {
	color: var(--status-danger);
	margin-left: var(--gap-hairline);
	flex: none;
}

.endlessDropdown__placeholder {
	min-width: 0;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	text-align: start;
	font-size: var(--font-size-body);
}

/* Hidden native <select> — present only for form submission; the combobox heading is the visible control. */
.endlessDropdown__nativeSelect {
	display: none;
}

.endlessDropdown__headingArea {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
	padding: 0 var(--pad-card);
	box-sizing: border-box;
}

.endlessDropdown__expandedArea {
	height: 100%;
	display: grid;
	grid-template-rows: auto auto minmax(0, 1fr);
	gap: var(--gap-inline);
	padding: var(--pad-dense);
	box-sizing: border-box;
}

.endlessDropdown__toggleBar {
	width: min-content;
	justify-self: end;
}

/* clearable single-select: the pinned clear row + the scrolling bucket share the
   panel's flexible list row. min-height:0 lets the bucket shrink so it scrolls. */
.endlessDropdown__listArea {
	display: flex;
	flex-direction: column;
	min-height: 0;
	gap: var(--gap-tight);
}

/* The paged option list gets a bounded height so the bucket can window/scroll. */
.endlessDropdown__bucket {
	max-height: 14rem;
}

/* The pinned "clear selection" row — muted so it reads as the "none" affordance, not a data row. */
.endlessDropdown__clearOption {
	flex: none;
	color: var(--text-secondary);
	font-style: italic;
}

.endlessDropdown__option {
	width: 100%;
	cursor: pointer;
	margin: 0;
	padding: .45rem .5rem; /* intentional literal: kept byte-parallel with dropdown.css's .dropdown__option — +78% vertical on an unbounded option list */
	border-radius: var(--radius-button);
	box-sizing: border-box;
}

.endlessDropdown__option:hover {
	background-color: var(--surface-raised);
}

/* Keyboard cursor — a subtler highlight than a selection so it doesn't read as "selected". */
.endlessDropdown__currentOption {
	background-color: var(--lighter_grey, var(--surface-raised));
}

.endlessDropdown__option-checked {
	background-color: var(--surface-raised);
	font-weight: bold;
}

.endlessDropdown__headingArea-disabled {
	opacity: .5;
	cursor: not-allowed;
	pointer-events: none;
}

:root[data-viewport="phone"] {

	.endlessDropdown__view,
	.endlessDropdown__option {
		min-height: var(--touch-target-primary);
	}

	.endlessDropdown__placeholderNode-shrunk,
	.endlessDropdown__placeholderNodeProxy {
		font-size: var(--font-size-caption);
	}
}

/**
* entityImageAndName.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-17 Initial Version
* @version 2026-July-16 Mobile block converted from width media query to the `data-mobile` axis (#1637)
* @version 2026-July-17 Phone rules re-gated :root[data-mobile] → :root[data-viewport="phone"] (decision 0004 phase 1, #1684)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.entityImageAndName__view {
	display: flex;
	align-items: center;
	position: relative;
	gap: var(--gap-stack);
}

.entityImageAndName__img {}

:root[data-theme="cyber"] .entityImageAndName__img {
	display: block;
	border: none;
	/* box-shadow: var(--elevation-surround); */
	background-color: transparent;
	border-radius: 0;
	-webkit-border-radius: 0;
	-moz-border-radius: 0;
	background-repeat: no-repeat;
	background-position: center;
	cursor: pointer;
	clip-path: polygon(0.5rem 66%, 34% calc(100% - 0.5rem), calc(100% - .5rem) calc(100% - .5rem), calc(100% - .5rem) .5rem, .5rem .5rem);
}

:root[data-theme="modern"] .entityImageAndName__img {
	display: block;
	border: none;
	/* box-shadow: var(--elevation-surround); */
	background-color: var(--surface-raised);
	border-radius: var(--radius-circle);
	-webkit-border-radius: var(--radius-circle);
	-moz-border-radius: var(--radius-circle);
	background-repeat: no-repeat;
	background-position: center;
	cursor: pointer;
	clip-path: inset(0.5rem round 4.5rem);
	transition: clip-path var(--motion-slow) var(--ease-enter);
}

:root[data-theme="cyber"] .entityImageAndName__img-expanded {
	clip-path: polygon(0% 100%, 0% 100%, 100% 100%, 100% 0%, 0% 0%);
}

:root[data-theme="modern"] .entityImageAndName__img-expanded {
	clip-path: inset(0rem round 0rem);
}

.entityImageAndName__img-small {
	height: 8rem;
	width: 8rem;
	margin-bottom: var(--gap-tight);
}

.entityImageAndName__img-medium {
	height: 10rem;
	width: 10rem;
	margin-bottom: var(--gap-dense);
}

.entityImageAndName__img-large {
	height: 13rem;
	width: 13rem;
}

.entityImageAndName__name {
	/* color: var(--text-primary); */
}

.entityImageAndName__name-reverse {
	/* color: var(--text-on-brand); */
}

.entityImageAndName__profileImageView {
	display: flex;
	flex-direction: column;
}

.entityImageAndName__imageNode {
	height: 10rem;
	width: 10rem;
	position: relative;
}

.entityImageAndName__imageNode::after {
	content: '';
	position: absolute;
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	pointer-events: none;
}

:root[data-theme="modern"] .entityImageAndName__imageNode::after {
	border-radius: var(--radius-circle);
	-webkit-border-radius: var(--radius-circle);
	border: .2rem solid var(--brand-primary);
	box-sizing: border-box;
}

:root[data-theme="cyber"] .entityImageAndName__imageNode::after {
	clip-path: polygon(0 0, 0 68%, 31% 100%, 100% 100%, 100% 0, 2px 0, 2px 2px, calc(100% - 2px) 2px, calc(100% - 2px) calc(100% - 2px),
			calc(31% + 1px) calc(100% - 2px), 2px calc(68% - 1px), 2px 0);
	background-color: var(--brand-primary);
}

.entityImageAndName__imageNode-hiddenFrame::after {
	opacity: 0;
}

.entityImageAndName__previousImgsContainer {
	z-index: 2;
	transition: all var(--motion-slow) var(--ease-enter) 0s;
	border-radius: var(--radius-button);
	height: 0rem;
	width: calc(100% - 30rem);
	max-width: 100rem;
	left: 50%;
	transform: translateX(-50%);
	padding: 0;
	position: fixed;
	top: calc(100vh - 18rem);
}

/* The trailing delay is a deliberate stagger — the previous-images tray waits
   for the image expand to finish before it opens. Both halves now ride the
   ladder (4-value shorthand: property, duration, easing, delay).
   TODO: this reveals by animating `height: 0rem → 10rem`, a layout animation;
   a transform-based reveal needs a wrapper element. */
.entityImageAndName__previousImgsContainer-expanded {
	transition: all var(--motion-slow) var(--ease-enter) var(--motion-slow);
	height: 10rem;
	box-shadow: var(--elevation-surround);
}

.entityImageAndName__nameNode {
	display: flex;
	align-items: center;
}

.entityImageAndName__entitiesContainer {
	display: grid;
	gap: var(--gap-inline);
	padding: var(--pad-card);
	/* height: 100%; */
	height: fit-content;
}

.entityImageAndName__entitiesContainer>* {
	padding: var(--pad-dense);
	border-radius: var(--radius-button);
}

.entityImageAndName__entitiesContainer>*:hover {
	background-color: var(--surface-hover);
}

/* Mobile: the desktop `width: calc(100% - 30rem)` assumes the side panel; on narrow
   screens that leaves the gallery bar too cramped (or off-screen). Span the viewport
   instead so the scroll area + actions pillbox stay reachable. Gated on the
   `data-viewport="phone"` band (JS-synced from PHONE_MAX_PX), never a
   width media query — see decisions/0004. */
:root[data-viewport="phone"] .entityImageAndName__previousImgsContainer {
	left: 1rem;
	right: 1rem;
	width: auto;
	max-width: none;
	transform: none;
}

/**
 * hamburger.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2020-05-13 Initial Version 
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 */

.hamburger__view {
    cursor: pointer;
    height: 3rem;
    width: 2rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 2;
}

.hamburger__lines__top, .hamburger__lines__middle, .hamburger__lines__bottom {
    border-radius: var(--radius-card);
    height: .3rem;
    background-color: var(--brand-accent);
}

.hamburger__lines__top {
    width: 2rem;
    margin: -1rem auto auto auto; /* intentional literal: negative optical offset — no token expresses a negative space */
}

.hamburger__lines__middle {
    width: 1rem;
}

.hamburger__lines__bottom {
    width: 2rem;
    margin: var(--gap-stack) auto auto auto;
}

.hamburger__lines__middle-x {
    width: 0rem;
}

.hamburger__lines__top-x {
    transform: translateY(1.3rem) rotate(45deg);
}

.hamburger__lines__bottom-x {
    transform: translateY(-1.35rem) rotate(-45deg);
}
/**
 * TabHeaderBar.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2020-05-05 Initial Version
 * @version 2026-May-25 Split outer/inner; divider rules move to inner buttonSelector
 * @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
 */

/* Outer wrapper — flex container that hosts the inner buttonSelector + accepts parent layout classes */
.tabHeaderBar__view {
	display: flex;
	height: fit-content;
	/* todo: remove, commented for scrolling */
	/* width: fit-content; */
	/* todo: remove, added to see all options in mobile */
	overflow: scroll;
	scrollbar-width: none;
	align-items: center;
	color: var(--text-primary);
}

/* Inner buttonSelector — direct parent of the tab buttons; lays them out and carries between-tab dividers */
.tabHeaderBar__buttonSelector {
	display: flex;
	align-items: center;
}

.tabHeaderBar__buttonSelector-vertical {
	flex-direction: column;
	align-items: start;
}

.tabHeaderBar__buttonSelector:not(.tabHeaderBar__buttonSelector-vertical)> :not(:first-child) {
	border-left: .1rem solid var(--border-default);
	border-radius: 0;
	padding-left: var(--pad-card);
}

.tabHeaderBar__buttonSelector:not(.tabHeaderBar__buttonSelector-vertical)> :not(:last-child) {
	margin-right: var(--gap-tile);
}

.tabHeaderBar__buttonSelector-vertical> :not(:last-child) {
	border-bottom: .1rem solid var(--border-default);
	border-radius: 0;
	padding-bottom: var(--pad-row);
}

.tabHeaderBar__buttonSelector-vertical> :not(:first-child) {
	margin-top: var(--gap-stack);
}

/* Per-tab styling */
.tabHeaderBar__tab {
	cursor: pointer;
	display: flex;
	gap: var(--gap-inline);
	align-items: end;
}

.tabHeaderBar__tab:hover,
.tabHeaderBar__tab:focus,
.tabHeaderBar__tab:active {
	color: var(--brand-accent);
}

.tabHeaderBar__tab[aria-selected='true'] {
	fill: var(--brand-accent);
	color: var(--brand-accent);
}

/**
* slider.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-05-22 Initial Version
* @version 2026-July-22 Focus ring proxied from the visually-hidden native input onto the visible track; span visuals get inline-block for sizing.
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
*/

.slider__view {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: var(--gap-tile);
	align-items: center;
}

.slider__sliderContainer {
	background-color: var(--surface-sunken);
	position: relative;
	display: inline-block;
	cursor: pointer;
	border-radius: var(--radius-pill);
	transition: background-color var(--motion-base) var(--ease-standard);
}

/* Focus lands on the hidden input; project the ring onto the visible track (WCAG 2.4.11).
   `input + track` is safe: render() always emits the input immediately before the track. */
.slider__input:focus-visible + .slider__sliderContainer {
	outline: var(--focus-ring-width) solid var(--focus-ring-color);
	outline-offset: var(--focus-ring-offset);
}

.slider__sliderContainer-checked {
	background-color: var(--status-success);
}

.slider__toggleKnob {
	background-color: var(--surface-card);
	position: absolute;
	top: 0;
	left: 0;
	border-radius: var(--radius-avatar);
	box-shadow: var(--elevation-surround);
	transition: transform var(--motion-base) var(--ease-standard);
}

/* Small */
.slider__sliderContainer-small {
	width: 2.75rem;
	height: 1.5rem;
}

.slider__toggleKnob-small {
	width: 1.5rem;
	height: 1.5rem;
}

.slider__sliderContainer-small .slider__toggleKnob-checked {
	transform: translateX(1.25rem);
}

/* Medium */
.slider__sliderContainer-medium {
	width: 3.5rem;
	height: 2rem;
}

.slider__toggleKnob-medium {
	width: 2rem;
	height: 2rem;
}

.slider__sliderContainer-medium .slider__toggleKnob-checked {
	transform: translateX(1.5rem);
}

/* Large */
.slider__sliderContainer-large {
	width: 4.25rem;
	height: 2.5rem;
}

.slider__toggleKnob-large {
	width: 2.5rem;
	height: 2.5rem;
}

.slider__sliderContainer-large .slider__toggleKnob-checked {
	transform: translateX(1.75rem);
}
/**
* multiStepSlider.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-May-10 Initial Version
* @version 2026-May-14 Segmented-pill layout for both modes; text mode gets a circular knob highlight behind the active label.
* @version 2026-June-23 Conform to the theme cascade: replace raw --dark_grey palette refs with adaptive semantic role tokens (--surface-sunken / --text-secondary / --text-primary / --text-on-brand / --brand-primary / --status-success).
* @version 2026-July-02 Animate collapse/expand for the text variant too: concrete base max-width + max-width/padding/opacity transitions (were icons-only), overflow clip + nowrap so labels reveal instead of wrapping mid-animation.
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.multiStepSlider__view {
	display: inline-flex;
	flex-direction: column;
	gap: var(--gap-tile);
}

.multiStepSlider__track {
	position: relative;
	display: flex;
	align-items: stretch;
	cursor: pointer;
	border-radius: var(--radius-card);
}

.multiStepSlider__stop {
	flex: 1 0 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	position: relative;
	user-select: none;
	cursor: pointer;
}

.multiStepSlider__knob {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: 0;
	border-radius: var(--radius-card);
	transition: all var(--transition-base), left 0s, width 0s;
	z-index: 0;
}

.multiStepSlider__view-text .multiStepSlider__track-text {
	background-color: var(--surface-sunken);
	padding: 0.3rem; /* intentional literal: coupled to .multiStepSlider__knob's matching 0.3rem inset — the knob must sit exactly inside the track padding */
}

.multiStepSlider__view-text .multiStepSlider__stop {
	padding: var(--pad-cell) var(--pad-card);
	color: var(--text-secondary);
	overflow: hidden;
	max-width: 12rem;
	/* transition: color 0.2s ease, max-width 0.25s ease, opacity 0.2s ease, padding 0.25s ease; */
}

.multiStepSlider__view-text .multiStepSlider__stop-selected {
	color: var(--text-on-brand);
}

.multiStepSlider__view-text .multiStepSlider__stopLabel {
	font-weight: bold;
	letter-spacing: 0.02em;
	color: inherit;
	white-space: nowrap;
}

.multiStepSlider__view-text .multiStepSlider__knob {
	top: 0.3rem;
	bottom: 0.3rem;
	background-color: var(--brand-primary);
	box-shadow: var(--elevation-raised);
}

.multiStepSlider__view-icons {
	--multiStepSlider-stop-color: var(--text-secondary);
	--multiStepSlider-stop-hover-color: var(--text-primary);
	--multiStepSlider-stop-selected-color: var(--status-success);
}

.multiStepSlider__view-icons .multiStepSlider__track-icons {
	gap: var(--gap-tile);
	padding: var(--pad-cell);
	transition: all 0.25s ease;
}

.multiStepSlider__view-icons.multiStepSlider__view-collapsed .multiStepSlider__track-icons {
	padding: 0 var(--pad-cell);
}

.multiStepSlider__view-icons .multiStepSlider__knob {
	display: none;
}

.multiStepSlider__view-icons .multiStepSlider__stop {
	color: var(--multiStepSlider-stop-color);
	overflow: hidden;
	max-width: 4rem;
	transition: color 0.15s ease, max-width 0.25s ease, opacity 0.2s ease, padding 0.25s ease;
}

.multiStepSlider__view-icons .multiStepSlider__stop:hover {
	color: var(--multiStepSlider-stop-hover-color);
}

.multiStepSlider__view-icons .multiStepSlider__stop-selected {
	color: var(--multiStepSlider-stop-selected-color);
}

.multiStepSlider__view-icons .multiStepSlider__stopIcon {
	fill: currentColor;
}

.multiStepSlider__view-icons .multiStepSlider__labels {
	display: flex;
	gap: var(--gap-tile);
}

.multiStepSlider__view-icons .multiStepSlider__label {
	flex: 1 0 0;
	text-align: center;
	user-select: none;
	cursor: pointer;
}

.multiStepSlider__view-icons .multiStepSlider__label-selected {
	font-weight: bold;
}

.multiStepSlider__view-collapsed .multiStepSlider__stop:not(.multiStepSlider__stop-selected) {
	max-width: 0;
	padding: 0;
	opacity: 0;
	pointer-events: none;
}

.multiStepSlider__view-collapsed .multiStepSlider__track {
	gap: 0;
}

/**
* colorSchemeSelector.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-May-14 Initial Version (as darkModeSelector.css)
* @version 2026-May-20 Renamed: darkModeSelector → colorSchemeSelector
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-August-04 Restore the collapsed-state `padding: 0 var(--pad-cell)` so the pill sits vertically flush (#1884; regression from #1821 round-2)
*/

.colorSchemeSelector__view {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background-color: var(--surface-page);
	border: 1px solid var(--border-default);
	border-radius: var(--radius-pill);
	padding: var(--pad-cell);
	--multiStepSlider-stop-selected-color: var(--status-success);
}

.colorSchemeSelector__slider-collapsed {
	border-color: transparent;
	background-color: transparent;
	padding: 0;
}

/**
* depthSelector.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-Jun-19 Initial Version (sibling of colorSchemeSelector.css)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-August-04 Restore the collapsed-state `padding: 0 var(--pad-cell)` so the pill sits vertically flush (#1884; regression from #1821 round-2)
*/

.depthSelector__view {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background-color: var(--surface-page);
	border: 1px solid var(--border-default);
	border-radius: var(--radius-pill);
	padding: var(--pad-cell);
	--multiStepSlider-stop-selected-color: var(--status-success);
}

.depthSelector__slider-collapsed {
	border-color: transparent;
	background-color: transparent;
	padding: 0;
}

/**
* atom.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-05-31 Initial Version
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
*/

.atom__view {
    position: absolute;
    top: 0;
    left: 0;
    height: 100dvh;
    width: 100dvw;
    z-index: 2;
}
/**
* ksiCircle.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
*/

.ksiCircle__view {
    background-color: rgba(0,0,0,.3);
    position: absolute;
    width: 100dvw;
    height: 100dvh;
    z-index: 2;
    display: flex;
}

.ksiCircle__gif {
    margin: auto;
    width: 50%;
}
/**
* loadingIndicators.css
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-04 Initial Version — LoadingBar + LoadingOverlay styles (#15). Role/brand
*          tokens only; both animations sit behind the shared reduced-motion guard.
* @version 2026-July-27 Added shared `spinnerRotate` keyframe for arc/half-circle
*          button-loading spinners. Consumers add their own reduced-motion entry.
* @version 2026-July-28 spinnerRotate now carries a cubic-bezier ease-in-out
*          inside its 0% keyframe (feels less mechanical than pure linear).
* @version 2026-July-28 Added `.loadingRing` primitive (3/4-arc ring via ::after,
*          2×→0.5 crispness trick) + `.loadingRing--spinning` motion modifier;
*          consumers drop the pair as a child element.
* @version 2026-August-04 Scrim-child narration re-synced to .ksiCircle__view's dvw/dvh (#1822)
*/

/* ---- LoadingBar — top-of-surface indeterminate slider ---- */

/* The track always reserves its height so showing/hiding the bar never reflows
   the content below it; only the background + indicator toggle. */
.loadingBar__track {
	position: relative;
	height: .4rem;
	width: 100%;
	overflow: hidden;
	border-radius: var(--radius-card);
	background-color: transparent;
}

.loadingBar__track-active {
	background-color: var(--surface-hover);
}

.loadingBar__indicator {
	display: none;
	position: absolute;
	top: 0;
	left: -40%;
	height: 100%;
	width: 40%;
	border-radius: inherit;
	/* Matches the determinate .progressBar fill (baseElements.css). */
	background-color: var(--brand-primary);
}

.loadingBar__track-active .loadingBar__indicator {
	display: block;
	animation: loadingBarSlide 1.2s ease-in-out infinite;
}

/* Pure `transform` so the sweep stays on the compositor; animating `left` forced
   layout+paint every frame. -40% start + 40% width + translateX 350% of own width
   (= 140% of the track) lands at the old 100% endpoint. */
@keyframes loadingBarSlide {
	0% {
		transform: translateX(0);
	}

	100% {
		transform: translateX(350%);
	}
}

/* ---- Spinner rotation — shared arc-spinner motion ---- */

@keyframes spinnerRotate {
	0% {
		animation-timing-function: cubic-bezier(0.5856, 0.0703, 0.4143, 0.9297);
		transform: rotate(0);
	}

	100% {
		transform: rotate(360deg);
	}
}

/* ---- .loadingRing — a reusable 3/4-arc spinner ring ---- */

.loadingRing {
	display: inline-block;
	position: relative;
	width: 1em;
	height: 1em;
	color: inherit;
	box-sizing: content-box;
}

.loadingRing::after {
	content: '';
	display: block;
	width: 2em;
	height: 2em;
	box-sizing: border-box;
	border-radius: var(--radius-circle);
	border: .3em solid currentColor;
	border-left-color: transparent;
	transform-origin: 0 0;
	transform: translateZ(0) scale(0.5);
	backface-visibility: hidden;
}

.loadingRing--spinning {
	animation: spinnerRotate .8s infinite;
}

/* ---- LoadingOverlay — blocking scrim hosting the KsiCircle gif ---- */

.loadingOverlay__scrim {
	display: none;
}

/* Fixed full-viewport scrim; the nested .ksiCircle__view (position:absolute,
   100dvw/100dvh) anchors to it and fills the same box. z-index above the
   mainView floating-panel background (900, displayOverlay.css). */
.loadingOverlay__scrim-active {
	display: flex;
	position: fixed;
	inset: 0;
	z-index: 901;
	background-color: var(--surface-overlay);
}

/* Reduced-motion guard (mirrors the .loadingPlaceholder shimmer guard in
   baseElements.css): the static bar still shows, just without the slide, and
   the ring freezes in place. */
@media (prefers-reduced-motion: reduce) {
	.loadingBar__track-active .loadingBar__indicator {
		animation: none;
		left: 0;
		width: 100%;
	}

	.loadingRing--spinning {
		animation: none;
	}
}

/**
* resultIndicator.css
* @author Alejandro J. De Jesus Reyes <alejandro.dejesus@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-29 Initial Version — generic paint for the ResultIndicator's
*         checkmark/X (extracted from button.css). Layout/positioning stays with
*         the consumer; this file owns only the stroke look + role-token color.
* @version 2026-August-05 `.resultIndicator__view` wrapper uses `display: contents`
*         so the framework's stable-root refactor doesn't add a layout box; the
*         state child (ring / ✓ / ✗) positions relative to the consumer's block.
*/

.resultIndicator__view {
	display: contents;
}

.resultIndicator-success,
.resultIndicator-fail {
	fill: none;
	stroke-width: 3;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.resultIndicator-success path,
.resultIndicator-fail path {
	stroke-dasharray: 100;
	stroke-dashoffset: 100;
}

.resultIndicator-success {
	stroke: var(--status-success);
}

.resultIndicator-fail {
	stroke: var(--status-danger);
}

/**
* button.css
* @author Alejandro J. De Jesus Reyes <alejandro.dejesus@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-27 Initial Version — .button-loading modifier for the Button
*         component. Owns paint + reduced-motion guard for the half-circle spinner;
*         the shared spinnerRotate keyframe lives in loadingIndicators.css.
* @version 2026-July-28 Loading paint moved to `.loadingRing` (loadingIndicators.css);
*          this file owns button-side state (label hide, click block, icon suppression).
* @version 2026-July-28 Added `.button-hold` + `.button-holdIndicator` for
*          hold-to-activate — SVG stroke driven via `stroke-dashoffset`.
* @version 2026-July-29 Success/fail icon paint moved to resultIndicator.css; this file
*          keeps only the button-local absolute-centered positioning under .button-loading.
*/

.button-loading {
	position: relative;
	color: transparent;
	text-shadow: none;
	pointer-events: none;
	cursor: wait;
}

.button-loading.button-lightBackground {
	background-color: var(--brand-accent);
}

.button-loading.button-darkBackground {
	background-color: transparent;
}

.button-loading.button-danger {
	background-color: transparent;
}

.button-loading .loadingRing {
	position: absolute;
	top: 50%;
	left: 50%;
	margin: -.5em 0 0 -.5em;
	color: var(--brand-primary);
	font-size: 1.4em; /* intentional literal: em-scale knob for the loadingRing's own 1em/2em children — proportional to button text, no --font-size-* rung is proportional */
}

.button-loading .resultIndicator-success,
.button-loading .resultIndicator-fail {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 1.4em;
	height: 1.4em;
	margin: -.7em 0 0 -.7em;
}

.button-hold {
	position: relative;
	user-select: none;
	touch-action: none;
}

.button-holdIndicator {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	display: block;
	overflow: hidden;
	border-radius: inherit;
}

.button-holdIndicator path {
	fill: none;
	stroke: var(--brand-primary);
	stroke-width: 3;
	stroke-dasharray: 100;
	stroke-dashoffset: 100;
}

.button-danger {
	.button-holdIndicator path {
		stroke: var(--status-danger);
	}
}

/**
* sideBySideCalendar.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-February-18 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
*/

.sideBySideCalendar__view {
	display: flex;
	flex-wrap: wrap;
	gap: var(--gap-section);
	justify-content: center;
}

/**
* graph.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-06-19 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.graph__view {
	display: grid;
	grid-template-areas: 'graph_yAxisLabel graph_yAxis graph_topBuffer' 'graph_yAxisLabel graph_yAxis graph_canvas' 'graph_yAxisLabel graph_yAxis graph_xAxis' '. graph_xAxisLabel graph_xAxisLabel';
	grid-template-rows: 1rem 1fr auto auto;
	grid-template-columns: auto auto 1fr;
	background-color: var(--surface-card);
	backdrop-filter: var(--surface-blur);
	-webkit-backdrop-filter: var(--surface-blur);
}

.graph__yAxis,
.graph__xAxis {
	background-color: var(--surface-card);
}

.graph__yAxis {
	grid-area: graph_yAxis;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	align-items: center;
	padding: var(--pad-dense) var(--pad-card);
}

.graph__yAxis__tickArea {
	grid-area: graph_canvas;
	position: relative;
	pointer-events: none;
}

.graph__yAxisLabel {
	grid-area: graph_yAxisLabel;
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.graph__yAxisLabel>* {
	transform: rotate(-90deg);
}

.graph__xAxisLabel {
	grid-area: graph_xAxisLabel;
	display: flex;
	justify-content: center;
	padding: var(--pad-dense);
}

.graph__xAxis {
	grid-area: graph_xAxis;
	display: flex;
	padding-right: var(--pad-card);
	justify-content: space-between;
}

.graph__yAxis__cero {
	margin: auto auto 0 auto;
}

.graph__yAxis__mid {
	margin: auto;
}

.graph__yAxis__last {
	margin: 0 auto auto auto;
}

/* Axis ticks are the textbook tabular case — they must align down the gutter.
   They are `getHeading`s (LineGraph.js:282), so they also inherited
   `--font-display`; pinned to the body face like every other figure. */
.graph__yAxis__tick {
	position: absolute;
	right: 100%;
	padding-right: var(--pad-card);
	font-family: var(--font-body);
	font-variant-numeric: tabular-nums;
	/* The tick centres on its gridline with translateY(50%) — half its OWN box
	   height — so its line box must not grow. `body` now sets --line-height-body
	   (1.5) where this inherited the UA's `normal` (~1.15), which pushed each
	   tick 1-2px off its gridline. Pin the leading; the centring hack depends on
	   it. Same root cause as the .taskTile row-loss fix: a component that
	   assumed `normal` meeting the roomy body leading. */
	line-height: var(--line-height-tight);
	transform: translateY(50%);
	opacity: .5;
	pointer-events: none;
	white-space: nowrap;
}

.graph__xAxis__cero {
	margin: auto auto auto 0;
}

.graph__xAxis__mid {
	margin: auto;
}

.graph__xAxis__last {
	margin: auto 0 auto auto;
}

.graph__canvas {
	grid-area: graph_canvas;
	color: var(--brand-accent);
	/* color: linear-gradient(45deg, var(--Main_Color) 0%, var(--brand-accent) 100%); */
	width: 100%;
	height: 100%;
}

/**
* newIntervalView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-23 Initial Version
* @version 2026-July-08 Cross-member add picker occupies the heading grid slot
* @version 2026-July-29 Spacing literals onto the role-token ladder; button row laid out by gap instead of per-child margins
*/

.newIntervalView__view {
	display: grid;
	grid-template-areas: 'newIntervalView_teamMemberHeading newIntervalView_totalTime' 'newIntervalView_sideBySideCalendar newIntervalView_sideBySideCalendar' '. newIntervalView_buttonContainer';
	grid-template-rows: auto 1fr auto;
	gap: var(--gap-tile);
	align-items: center;
}

.newIntervalView__teamMemberHeading,
.newIntervalView__memberPicker {
	grid-area: newIntervalView_teamMemberHeading;
	margin: auto auto auto 0;
}

.newIntervalView__memberPicker {
	max-width: 20rem;
}

.newIntervalView__sideBySideCalendar {
	grid-area: newIntervalView_sideBySideCalendar;
}

.newIntervalView__buttonContainer {
	grid-area: newIntervalView_buttonContainer;
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: var(--gap-inline);
	padding-inline-end: var(--pad-card);
	height: 100%;
}

/* Running interval total — tabular figures so the digits don't jitter per tick. */
.newIntervalView__totalTime {
	grid-area: newIntervalView_totalTime;
	margin: auto 0 auto auto;
	font-variant-numeric: tabular-nums;
}

/**
* fromToDatePicker.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-03 Expand icon rides the shared large Icon preset (2rem) — bespoke 2.1rem box dropped, glyph no longer undersized (#1239)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.fromToDatePicker__view {
	position: relative;
}

.fromToDatePicker__headingContainer {
	display: grid;
	grid-template-areas: '. fromToDatePicker_heading fromToDatePicker_expandImg';
	grid-template-columns: 1fr auto 1fr;
	padding-bottom: var(--pad-card);
	gap: var(--gap-section);
	align-items: center;
}

.fromToDatePicker__heading {
	grid-area: fromToDatePicker_heading;
}

.fromToDatePicker__expandImg {
	grid-area: fromToDatePicker_expandImg;
	cursor: pointer;
	justify-self: start;
	fill: var(--brand-accent);
	transform: rotate(90deg);
}

.fromToDatePicker__expandImg-transform {
	transform: rotate(270deg);
}

.fromToDatePicker__sideBySideContainer {
	width: 100%;
	max-height: 0;
	overflow: hidden;
}

.fromToDatePicker__sideBySideContainer-expanded {
	max-height: fit-content;
}

/**
* messageParticipantsTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-07-16 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.messageParticipantsTile__view {
    display: flex;
    flex-direction: column;
    padding: var(--pad-row) var(--pad-card);
    margin: var(--gap-stack) auto;
    border-radius: var(--radius-button);
    cursor: pointer;
}
/**
* deleteProjectView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.deleteProjectView__view {
    width: fit-content;
    background: var(--surface-page);
    margin: 10rem auto auto 50vw; /* intentional literal: dialog top offset + the 50vw/translateX(-50%) centring idiom */
    transform: translateX(-50%);
    box-shadow: var(--elevation-overlay);
    display: grid;
    /* The dialog had no padding at all under the global `* { padding: 0 }` reset —
       heading and buttons sat flush against the shadowed edge. */
    padding: var(--pad-sheet);
    border-radius: var(--radius-sheet);
    gap: var(--gap-stack);
}

.deleteProjectView__buttonArea {
    display: flex;
    justify-content: space-around;
}
/**
* deleteClientView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.deleteClientView__view {
    width: fit-content;
    background: var(--surface-page);
    margin: 10rem auto auto 50vw; /* intentional literal: dialog top offset + the 50vw/translateX(-50%) centring idiom */
    transform: translateX(-50%);
    box-shadow: var(--elevation-overlay);
    display: grid;
    /* The dialog had no padding at all under the global `* { padding: 0 }` reset —
       heading and buttons sat flush against the shadowed edge. */
    padding: var(--pad-sheet);
    border-radius: var(--radius-sheet);
    gap: var(--gap-stack);
}

.deleteClientView__heading {}

.deleteClientView__question {}

.deleteClientView__buttonArea {
    display: flex;
    justify-content: space-around;
}
/**
* messageTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-07-28 Initial Version
* @version 2026-July-04 Thread affordance + reply-chip rules (#1454)
* @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the message buttons always (#1641)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-August-14 Floating action strip reads --surface-raised — the white literal was a light-mode-only surface (#1840)
*/

.messageTile__view,
.messageTile__view-selfEntity {
	anchor-scope: all;
	max-width: 60%;
	display: grid;
}

.messageTile__view-selfEntity {
	align-self: end;
	justify-items: end;
}

.messageTile__view {
	margin: var(--gap-dense) auto var(--gap-dense) var(--gap-stack);
}

.messageTile__buttons {
	display: flex;
	align-items: center;
	padding: var(--pad-cell);
	/* The `0s` entries exclude the anchor-positioned offsets so an anchor recalc
	   is instant. `left 0s` was missing: the default (non-self-entity) variant
	   positions with `left`, so the button strip used to slide whenever the
	   anchor moved. The visible change here is a hover-reveal (opacity) → fast. */
	transition: all var(--motion-fast) var(--ease-enter), top 0s, right 0s, left 0s;
	border-radius: var(--radius-pill);
	border: 1px solid var(--app-Gray-mid);
	background-color: var(--surface-raised);
	position-anchor: --message-bubble;
	position: absolute;
	top: anchor(top);
	left: calc(anchor(left) - 0.5rem);
	transform: translateY(-50%);
}

.messageTile__view-selfEntity {
	margin: var(--gap-dense) var(--gap-stack) var(--gap-dense) auto;

	.messageTile__buttons {
		left: unset;
		right: calc(anchor(right) + 0.5rem);
	}
}

.messageTile__bubble__contentArea {
	display: flex;
	align-items: center;
	word-break: break-all;
}

.messageTile__bubble__contentArea-selfEntity {
	justify-content: end;
}

.messageTile__bubble {
	anchor-name: --message-bubble;
	background: var(--surface-card);
	border-radius: var(--radius-card) var(--radius-card) var(--radius-card) 0;
	margin: var(--gap-dense) var(--gap-stack);

	width: fit-content;
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the message action buttons behind it — touch sees them always. */
@media (hover: hover) {
	.messageTile__buttons {
		opacity: 0;
	}

	.messageTile__bubble:hover .messageTile__buttons {
		opacity: 1;
	}
}

.messageTile__bubble-selfEntity {
	background: var(--brand-accent);
	color: var(--text-on-brand);
	border-radius: var(--radius-card) var(--radius-card) 0 var(--radius-card);
	margin: var(--gap-stack) 0;
}

.messageTile__bubble__entityDisplayName {
	/* height: 2rem;
    width: 2rem;
    margin-top: 2rem; */
}

.messageTile__bubble__deletedText {
	font-style: italic;
	opacity: 0.75;
}

.messageTile__senderHeading {
	display: flex;
	margin: auto auto auto 4rem; /* intentional literal: avatar-aligned indent matched to the sender avatar column */
	gap: var(--gap-stack);
	align-items: center;
}

.messageTile__senderHeading__senderName,
.messageTile__dateHeading {
	opacity: .6;
}

.messageTile__senderHeading__senderName {
	margin-top: .2rem; /* intentional literal: 2px optical nudge — hairline, not a density step */
}

.messageTile__dateHeading {
	text-align: start;
}

.messageTile__dateHeading-selfEntity {
	text-align: end;
	/* margin: auto 1rem auto auto; */
}
/* Threads (#1454) */

.messageTile__threadButton {
	align-self: center;
}

.messageTile__threadChip {
	justify-self: start;
	width: auto;
	padding: var(--pad-cell) var(--pad-dense);
	border-radius: var(--radius-pill);
	font-size: smaller; /* intentional literal: relative keyword, not a scale step */
	color: var(--text-secondary);
	background: var(--surface-hover);
}

.messageTile__threadChip-selfEntity {
	justify-self: end;
}

/**
* itemMessageBoard.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-04 Initial Version — item message board tab (#1455)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.itemMessageBoard__view {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	min-height: 0;
}

.itemMessageBoard__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
}

.itemMessageBoard__bell--subscribed {
	filter: drop-shadow(0 0 2px var(--Badge_Success_Background, currentColor));
}

.itemMessageBoard__composer {
	display: flex;
	flex-direction: column;
	gap: var(--gap-tight);
}

.itemMessageBoard__composerForm {
	display: flex;
	gap: var(--gap-inline);
	align-items: center;
}

.itemMessageBoard__composerInput {
	flex: 1;
	min-width: 0;
}

.itemMessageBoard__replyChip {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.itemMessageBoard__threadList {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	overflow-y: auto;
	min-height: 0;
}

.itemMessageBoard__tile {
	display: flex;
	flex-direction: column;
	gap: var(--gap-tight);
}

.itemMessageBoard__tileMeta {
	display: flex;
	align-items: baseline;
	gap: var(--gap-inline);
}

.itemMessageBoard__tileAuthor {
	font-weight: 600;
}

.itemMessageBoard__tileDate {
	opacity: 0.7;
}

.itemMessageBoard__tileContent--deleted {
	opacity: 0.6;
	font-style: italic;
}

.itemMessageBoard__tileActions {
	display: flex;
	gap: var(--gap-inline);
	align-items: center;
}

/* The Reddit indent: each reply level nests one gutter deeper. */
.itemMessageBoard__replies {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	margin-left: var(--gap-stack);
	padding-left: var(--pad-row);
	border-left: 1px solid var(--Container_Border, currentColor);
}

.itemMessageBoard__empty {
	opacity: 0.7;
}

.itemMessageBoard__loadMore {
	align-self: center;
}

/**
* logo.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-August-14 Deleted the three rules only the commented-out Logo.js branch referenced; the classic/cyber mark colors stay (#1840)
*/

.logo__view {
    display: flex;
}

.logo__defaultBase-classic {
    fill: #1FFFFC;
}

.logo__defaultHighlight-classic {
    fill: #FF1D8E;
}

.logo__defaultBase-cyber {
    fill: #1FFFFC;
}

.logo__defaultHighlight-cyber {
    fill: #B6234F;
}

.logo__highlight {
    fill: var(--brand-accent);
}

.logo__main {
    fill: var(--text-secondary);
}
/**
* teamMemberChooser.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-07-29 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
*/

.teamMemberChooser__view {
	position: relative;
}

.teamMemberChooser__dropdown {
	width: 100%;
}

.teamMemberChooser__teamMemberSelectionPanel {
	background: var(--surface-card);
	padding: var(--pad-dense);
	display: grid;
	gap: var(--gap-dense);
}

.teamMemberChooser__entityImgArea {
	display: flex;
	flex-wrap: wrap;
}

.teamMemberChooser__entityImgArea>* {
	margin-right: var(--gap-inline);
}

.teamMemberChooser__entityTile {
	padding: var(--pad-dense);
	border-radius: var(--radius-dense);
}

.teamMemberChooser__entityTile:hover {
	background-color: var(--surface-sunken);
}

/**
* teamMemberRoleManagement.css
* @author Magdiel A. Marrero Rodríguez <magdiel.marrero@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-Jun-30 Initial Version (#1227)
* @version 2026-July-03 Ownership block (propose / pending / cancel) for the Owner handshake (#1250)
* @version 2026-July-15 Self-view notice slots into the Dropdown's row position (#1513) so chips still render on self.
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.teamMemberRoleManagement__view {
	/* Three rows: controls (18rem floor for chip-wrap growth), matrix (1fr — takes remaining space),
	   ownership block (auto — sized to content, pinned to the bottom when present). */
	display: grid;
	grid-template-rows: minmax(18rem, max-content) 1fr auto;
	grid-template-columns: minmax(0, 1fr);
	row-gap: var(--gap-section);
	height: 100%;
	padding: var(--pad-card);
}

.teamMemberRoleManagement__permissionMatrix {
	/* Anchor to the top of the 1fr area; height stays content-sized up to the row's ceiling. Thin divider
	   above with padding so the seam has breathing room. */
	align-self: start;
	min-height: 0;
	max-height: 100%;
	border-top: 0.1rem solid var(--border-default);
	padding-top: var(--pad-row);
}

.teamMemberRoleManagement__topRow {
	display: flex;
	align-items: flex-start;
	gap: var(--gap-tile);
}

.teamMemberRoleManagement__dropdown {
	flex: 0 0 auto;
	min-width: 12rem;
}

.teamMemberRoleManagement__chip {
	padding: var(--pad-cell) var(--pad-dense);
}

.teamMemberRoleManagement__chips {
	/* `flex-basis: 0` + `min-width: 0` let the container shrink below its
	   intrinsic content width so chips wrap instead of overflowing to the right
	   when the Dropdown consumes its share of the row. */
	flex: 1 1 0;
	min-width: auto;
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	/* Pin wrap rows to the top; without this the default `align-content: normal`/`stretch`
	   distributes free cross-axis space into wrap rows when the container is taller than its
	   natural row-sum (which happens because the parent grid row has an 18rem floor). */
	align-content: flex-start;
	gap: var(--gap-inline);
}

.teamMemberRoleManagement__emptyChips,
.teamMemberRoleManagement__selfNotice {
	color: var(--text-secondary, inherit);
	font-style: italic;
}

/* Slot the self notice into the Dropdown's row position so chips flow to the
   right just as they do in the non-self layout. */
.teamMemberRoleManagement__selfNotice {
	/* flex: 0 0 auto; */
	min-width: 12rem;
	margin: 0;
}

.teamMemberRoleManagement__ownershipRow {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--gap-inline);
	padding-block-start: var(--pad-card);
	border-block-start: 1px solid var(--border-default);
}

.teamMemberRoleManagement__ownershipLabel,
.teamMemberRoleManagement__ownershipPending {
	color: var(--text-secondary, inherit);
}

:root[data-viewport="phone"] .teamMemberRoleManagement__topRow {
	flex-direction: column;
	align-items: stretch;
}

:root[data-viewport="phone"] .teamMemberRoleManagement__dropdown,
:root[data-viewport="phone"] .teamMemberRoleManagement__selfNotice {
	min-width: 0;
	width: 100%;
}

:root[data-viewport="phone"] .teamMemberRoleManagement__chips {
	justify-content: flex-start;
}

/**
* teamMemberPermissionMatrix.css — read-only Resource × Action matrix with sticky header + first column.
*
* @author Magdiel A. Marrero Rodríguez <magdiel.marrero@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-15 Initial Version (#1513)
* @version 2026-July-20 Read theme role tokens directly instead of the legacy Capitalized_Snake aliases (frontend.md § CSS conventions).
* @version 2026-July-29 Spacing/type literals migrated onto the token contract's §Dense rungs — row chrome holds or tightens
* @version 2026-August-14 Dropped all 11 var() fallback arguments — noUnresolvedCssVars guarantees resolution, and two of them named colours the palette does not ship (#1840)
*/

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

.teamMemberPermissionMatrix__view {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	max-height: 100%;
	min-height: 0;
}

.teamMemberPermissionMatrix__headingRow {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--gap-tile);
	/* Lock at intrinsic height so a tall matrix doesn't squeeze the label — only the scroll box shrinks. */
	flex-shrink: 0;
}

.teamMemberPermissionMatrix__heading {
	margin: 0;
}

.teamMemberPermissionMatrix__actionsToggle {
	flex-shrink: 0;
}

.teamMemberPermissionMatrix__scroll {
	overflow: auto;
	flex: 1 1 auto;
	min-height: 0;
	border: 0.1rem solid var(--border-default);
	border-radius: var(--radius-card);
	background: var(--surface-card);
	/* Contain the sticky header/corner z-indexes to this subtree — without a
	   local stacking context they float above app chrome (navigation rail). */
	isolation: isolate;
}

.teamMemberPermissionMatrix__table {
	border-collapse: collapse;
	width: 100%;
	font-size: var(--font-size-body);
}

.teamMemberPermissionMatrix__headerRow {
	background: var(--surface-card);
}

.teamMemberPermissionMatrix__actionHeader,
.teamMemberPermissionMatrix__cornerCell {
	position: sticky;
	top: 0;
	z-index: 1;
	background: var(--brand-primary);
	color: var(--text-on-brand);
	padding: var(--pad-cell) var(--pad-dense);
	text-align: center;
	white-space: nowrap;
	border-right: 0.1rem solid var(--border-default);
	border-bottom: 0.1rem solid var(--border-default);
	font-weight: 600;
}

.teamMemberPermissionMatrix__cornerCell {
	left: 0;
	z-index: 2;
}

.teamMemberPermissionMatrix__rowLabel {
	position: sticky;
	left: 0;
	background: var(--surface-card);
	padding: var(--pad-cell) var(--pad-dense);
	text-align: left;
	white-space: nowrap;
	border-right: 0.1rem solid var(--border-default);
	border-bottom: 0.1rem solid var(--border-default);
	font-weight: 500;
	min-width: 12rem;
}

.teamMemberPermissionMatrix__rowLabel--child {
	padding-left: 2.25rem; /* intentional literal: tree indent for child permission rows — an indent measure, not page chrome */
	font-weight: 400;
	color: var(--text-secondary);
}

.teamMemberPermissionMatrix__rowLabelText {
	display: inline-block;
	/* Inherit the table's body size instead of `getSpan`'s default `.span-medium` rung. */
	font-size: inherit; /* intentional literal: relative keyword, not a scale step */
}

.teamMemberPermissionMatrix__chevron {
	background: transparent;
	border: none;
	cursor: pointer;
	padding: 0 var(--pad-cell) 0 0;
	font-size: 1em; /* intentional literal: relative keyword — the chevron tracks its row's size */
	color: var(--text-primary);
}

.teamMemberPermissionMatrix__chevron:hover {
	color: var(--brand-primary);
}

.teamMemberPermissionMatrix__cell {
	padding: var(--pad-cell) var(--pad-dense);
	text-align: center;
	border-right: 0.1rem solid var(--border-default);
	border-bottom: 0.1rem solid var(--border-default);
	font-family: var(--font-body);
}

.teamMemberPermissionMatrix__cell--granted {
	color: var(--status-success);
	font-weight: 600;
}

.teamMemberPermissionMatrix__cell--denied {
	color: var(--status-danger);
	font-weight: 500;
}

.teamMemberPermissionMatrix__cell--notApplicable {
	color: var(--text-secondary);
}

.teamMemberPermissionMatrix__childRow .teamMemberPermissionMatrix__cell {
	background: var(--surface-hover);
}

/* Drop the outermost cell borders so they don't stack against the scroll wrapper's own border. */
.teamMemberPermissionMatrix__table tr > *:last-child {
	border-right: none;
}

.teamMemberPermissionMatrix__table tr:last-child > * {
	border-bottom: none;
}

/* Drop the outermost cell borders so they don't stack against the scroll wrapper's own border. */
.teamMemberPermissionMatrix__table tr > *:last-child {
	border-right: none;
}

.teamMemberPermissionMatrix__table tr:last-child > * {
	border-bottom: none;
}

/**
* expandedTeamMemberTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.expandedTeamMemberTile__view {
    display: grid;
    grid-template-areas: 'expandedTeamMemberTile__TeamMemberDisplayName expandedTeamMemberTile__TeamMemberTime';
    gap: var(--gap-stack);
    width: 100%;
    justify-content: space-between;
    cursor: pointer;
    border: var(--border-shorthand);
    border-radius: var(--radius-button);
    padding: var(--pad-row);
    overflow: hidden;
    margin: var(--gap-stack) auto;
}

.expandedTeamMemberTile__view-selected {
    border-color: var(--brand-accent);
}

.expandedTeamMemberTile__TeamMemberDisplayName {
    grid-area: expandedTeamMemberTile__TeamMemberDisplayName;
}

/* Live per-second timer — tabular figures stop the digits jittering as it
   ticks. Selector case now matches ExpandedTeamMemberTile.js:55-56, which
   stamps `__TeamMemberDisplayName` / `__TeamMemberTime`; the grid-area rules
   previously spelled these with a lowercase `t` and matched nothing, so
   neither element ever received its grid area (#followup-to-ui-polish). */
.expandedTeamMemberTile__TeamMemberTime {
    grid-area: expandedTeamMemberTile__TeamMemberTime;
    font-variant-numeric: tabular-nums;
}

/**
* projectTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-03 Display-image column: figure spans both text rows (#1051)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.projectTile__view {
	cursor: pointer;
	display: grid;
	grid-template-columns: auto 1fr auto;
	gap: var(--gap-inline);
	align-items: center;
}

.projectTile__view-selected {
	border-color: var(--brand-accent);
}

/* Display image (initials fallback) — spans both text rows in the first column (#1051). */
.projectTile__initialsRoundHeading {
	grid-column: 1;
	grid-row: 1 / 3;
}

/* The loading/notFound/error arms each render a single child (skeleton row / error
   notice); span it across the grid so it doesn't collapse into the auto first column. */
.projectTile__view > :only-child {
	grid-column: 1 / -1;
}

.projectTile__projectName {
	grid-column: 2;
}

.projectTile__clientName {
	grid-row: 2/3;
	grid-column: 2;
	color: var(--text-secondary);
}

/* Shimmer stand-in for the client-name line while its enrichment fetch is
   pending — sized to the smaller text line it replaces. */
.projectTile__clientSkeleton {
	grid-row: 2/3;
	grid-column: 2;
	height: 1.2rem;
	min-width: 6rem;
	width: fit-content;
}

/* getChip badge — on-fill styling; the gradient fill rides inline `style` (getStopColor). */
.projectTile__deadline {
	grid-column: 3;
	color: var(--Badge_On_Fill_Font_Color);
	border: none;
}

/**
* clientTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.clientTile__view {
	display: grid;
	grid-template-columns: minmax(auto, 1fr) auto;
	cursor: pointer;
	padding: var(--pad-row) var(--pad-card);
	color: var(--text-primary);
	align-items: center;
}

.clientTile__view-selected {
	border-color: var(--brand-accent);
}

.clientTile__view::after {
	opacity: 1;
}

.clientTile__clientName {
	transition: none;
}

/**
* searchResultTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
*/

.searchResultTile__view {
	display: grid;
	border: solid 1px var(--brand-accent);
	padding: var(--pad-card);
	min-width: 15rem;
	height: 20rem;
	width: auto;
	max-width: 20rem;
	overflow: hidden;
}

.searchResultTile__view:focus,
.searchResultTile__view:hover {
	transform: scale(1.12);
}

.searchResultTile__entityDisplayImage {
	grid-row: 1/2;
	height: 10rem;
	width: 10rem;
	margin: auto;
}

.searchResultTile__heading {
	margin: auto;
	text-overflow: ellipsis;
	width: 100%;
}

.searchResultTile__viewProfileButton {
	margin: auto;
	font-size: var(--font-size-caption);
}

.searchResultTile__addAsTeamMemberButton {
	margin: auto;
	font-size: var(--font-size-caption);
}

/**
 * headerTiles.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2020-12-01 Initial Version 
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 */

.headerTiles__tile {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    padding: var(--pad-dense);
    border-radius: var(--radius-button);
    text-align: left;
    cursor: pointer;
}

.headerTiles__tile:hover {
    background: var(--surface-sunken);
    /* color: var(--text-on-brand); */
}

.headerTiles__tile-active, .headerTiles__tile-active:hover {
    background: transparent;
    color: var(--brand-accent);
}
/**
* performanceSummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-12-21 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.performanceSummary__view {
    /* margin: 1rem; */
    display: grid;
    grid-template-areas: 'performance__sumaryContainer_teamMemberPicker performance__sumaryContainer_total performance__sumaryContainer_dailyAverage' 'performance__sumaryContainer_teamMemberPicker performance__sumaryContainer_averageStart performance__sumaryContainer_averageStop';
    grid-template-columns: repeat(3, auto);
    grid-template-rows: repeat(2, 1fr);
    gap: var(--gap-stack);
    justify-content: space-between;
    height: 9rem;
}
/**
* connectionIcon.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-01-03 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.connectionIcon__view {
    display: block;
    position: relative;
    height: 8rem;
    width: 8rem;
}

.connectionIcon__circle {
    display: block;
    position: absolute;
    height: 1rem;
    width: 1rem;
    border: .2rem solid var(--text-on-brand);
    border-radius: var(--radius-avatar);
}

.connectionIcon__center {
    height: 2rem;
    width: 2rem;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.connectionIcon__upperLeft {
    height: .8rem;
    width: .8rem;
    top: 25%;
    left: 25%;
}

.connectionIcon__upperLeft::after {
    position: static;
    display: block;
    content: '';
    background-color: var(--text-on-brand);
    height: 1.1rem;
    width: .2rem;
    transform: translate(.7rem, .2rem) rotate(-45deg);
}

.connectionIcon__lowerLeft {
    left: 20%;
    bottom: 25%;
}

.connectionIcon__lowerLeft::after {
    display: block;
    content: '';
    background-color: var(--text-on-brand);
    height: 1.1rem;
    width: .2rem;
    transform: translate(.9rem, -.9rem) rotate(50deg);
}

.connectionIcon__upperRight {
    top: 20%;
    right: 25%;
}

.connectionIcon__upperRight::after {
    display: block;
    content: '';
    background-color: var(--text-on-brand);
    height: 1.2rem;
    width: .2rem;
    transform: translate(-.4rem, .5rem) rotate(40deg);
}

.connectionIcon__lowerRight {
    right: 15%;
    bottom: 15%;
    height: 1.5rem;
    width: 1.5rem;
}

.connectionIcon__lowerRight::after {
    display: block;
    content: '';
    background-color: var(--text-on-brand);
    height: 1.3rem;
    width: .2rem;
    transform: translate(-.5rem, -1rem) rotate(-45deg);
}

.disconnected {
    animation: wander .5s ease-in-out infinite;
}

.disconnected::after {
    transition: all var(--motion-slow) var(--ease-standard);
    background-color: inherit;
}
/**
* linkPreview.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-01-11 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.linkPreviewTile__view {
    width: 100%;
    display: grid;
    grid-template-areas: 'linkPreviewTile_img linkPreviewTile_title' 'linkPreviewTile_description linkPreviewTile_description' 'linkPreviewTile_link linkPreviewTile_link';
    align-items: center;
    grid-template-columns: auto 1fr;
    gap: var(--gap-inline);
}

.linkPreviewTile__img {
    grid-area: linkPreviewTile_img;
    height: 5rem;
    width: auto;
}

.linkPreviewTile__title {
    grid-area: linkPreviewTile_title;
    font-weight: 200;
}

.linkPreviewTile__description {
    grid-area: linkPreviewTile_description;
}

.linkPreviewTile__link {
    grid-area: linkPreviewTile_link;
}
/**
* stylePropTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-01-29 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
*/

.stylePropTile__view {
    width: 20rem;
    display: grid;
    /* Head row carries the secondary control(s): legacy entries can place an
       image icon (fileInput) AND a color swatch (colorInput) simultaneously;
       new deep-theming single controls (length/select) use the shared
       control slot, which overlaps the colorInput column. The text field
       always spans the full second row. */
    grid-template-areas: 'stylePropTile_head stylePropTile_fileInput stylePropTile_control' 'stylePropTile_textField stylePropTile_textField stylePropTile_textField';
    grid-template-columns: 4fr auto 1fr;
    gap: var(--gap-inline) var(--gap-tile);
    align-items: center;
}

.stylePropTile__header {
    grid-area: stylePropTile_head;
}

.stylePropTile__textField {
    grid-area: stylePropTile_textField;
    margin: auto;
    background: var(--surface-card);
    color: var(--text-primary);
}

.stylePropTile__colorInput,
.stylePropTile__numberInput,
.stylePropTile__selectInput,
.stylePropTile__controlPlaceholder {
    grid-area: stylePropTile_control;
}

.stylePropTile__numberInput {
    width: 5rem;
}

.stylePropTile__imageInput {
    grid-area: stylePropTile_fileInput;
    width: 2rem;
}

/**
* clientInfo.css
* @author Raúl E. Barroso <raul.barroso@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-April-22 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.clientInfo__view {
	padding: var(--pad-card);
	display: grid;
}

.clientInfo__infoContainer {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
	gap: var(--gap-section);
	width: auto;
	margin: var(--gap-stack);
}

.clientInfo__infoTypeContainer {
	height: fit-content;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
	grid-template-rows: auto;
	grid-auto-rows: 1fr;
	column-gap: var(--gap-stack);
	row-gap: var(--gap-dense);
	width: auto;

	.clientInfo__infoTypeHeader {
		grid-column: 1 / -1;
		font-weight: 500;
		text-align: start;
	}
}

/**
* deadlineTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-24 Initial Version
* @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the edit button always (#1641)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.deadlineTile__view {
	height: fit-content;
	position: relative;
	display: grid;
	grid-template-areas:
		'deadlineTile__header  deadlineTile__editButton'
		'deadlineTile__begin deadlineTile__end';
	grid-template-columns: 1fr auto;
	justify-content: space-between;
	padding: var(--pad-row);
	border: var(--border-shorthand);
	border-radius: var(--radius-button);
}

.deadlineTile__expandablePanel {
	padding: var(--pad-row);
}

.deadlineTile__header {
	grid-area: deadlineTile__header;
}

.deadlineTile__begin {
	grid-area: deadlineTile__begin;
}

.deadlineTile__end {
	grid-area: deadlineTile__end;
}

.deadlineTile__editButton {
	grid-area: deadlineTile__editButton;
	cursor: pointer;
	position: absolute;
	top: 0;
	right: 0;
	transform: translate(80%, -80%);
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the edit button behind it — touch devices see it always. */
@media (hover: hover) {
	.deadlineTile__editButton {
		opacity: 0;
	}

	.deadlineTile__view:hover .deadlineTile__editButton {
		opacity: 1;
	}
}

.newDeadlineView__cancelButton,
.newDeadlineView__saveButton {
	width: 6rem;
}
/**
* deadlineTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-24 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.newDeadlineView__view {
	height: 100%;
	display: grid;
	grid-template-rows: auto minmax(0, 1fr) auto;
	gap: var(--gap-tile);
	width: fit-content;
}

.newDeadlineView__buttonContainer {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: var(--gap-tile);
}
/**
* endlessBucket.css
* @author Magdiel A. Marrero Rodríguez <magdiel.marrero@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-April-30 Initial Version
* @version 2026-July-02 Skeleton loading states: first-load stand-in list + edge-of-window skeleton rows. @author Francisco J. Medina <francisco@seedburysquare.com>
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.endlessBucket__view {
	width: 100%;
	height: 100%;
}

.endlessBucket__list {
	width: 100%;
	min-height: 100%;
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);

	&>* {
		flex: none;
	}
}

.endlessBucket__list-reverse {
	justify-content: end;
}

/* First-load stand-in — mirrors .endlessBucket__list spacing so the
   skeleton → tiles swap doesn't reflow. */
.endlessBucket__firstLoadSkeleton {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
}

/* Edge-of-window fetch indicator — spaced off the item list like a row about
   to join it. */
.endlessBucket__edgeSkeleton {
	margin: var(--gap-stack) 0;
}

/**
* searchBar.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-03-08 Initial Version
* @version 2026-July-03 Neutralize type="search" UA chrome (#731 — getSearchBar became a real search input; keep the visual byte-identical)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
*/

.searchBar__view {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: var(--gap-inline);
}

/* getSearchBar is now `type="search"` (announced as a search field, WCAG 4.1.2).
   WebKit adds its own clear-button/decoration chrome to search inputs — strip it
   so the input looks exactly like the text input it used to be. (Lives here, next
   to the sole getSearchBar consumer; the base `.searchBar` rule is in
   compoundElements.css.) */
.searchBar::-webkit-search-cancel-button,
.searchBar::-webkit-search-decoration,
.searchBar::-webkit-search-results-button,
.searchBar::-webkit-search-results-decoration {
	-webkit-appearance: none;
	appearance: none;
}
/**
* projectHeader.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-May-30 Initial Version — extracted from projectPanel.css
* @version 2026-July-03 Display-image column: figure area added to the grid (#1051)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.projectHeader__view {
	display: grid;
	gap: var(--gap-tile);
	align-items: center;
	/* First column hosts the display image (initials fallback), spanning both rows (#1051). */
	grid-template-areas:
		'projectHeader_initialsRoundHeading projectHeader_displayName projectHeader_actionButtonsContainer'
		'projectHeader_initialsRoundHeading projectHeader_clientLink .';
	grid-template-columns: auto auto 1fr;
}

.projectHeader__initialsRoundHeading {
	grid-area: projectHeader_initialsRoundHeading;
}

.projectHeader__displayName {
	grid-area: projectHeader_displayName;
	text-align: left;
}

.projectHeader__status {
	grid-area: projectHeader_statusSlider;
	border: var(--border-shorthand);
	border-radius: var(--radius-card);
	padding: 0 var(--pad-dense);
	background-color: var(--brand-accent);
}

.projectHeader__statusSlider {
	grid-area: projectHeader_statusSlider;
}

.projectHeader__clientLink {
	grid-area: projectHeader_clientLink;
	justify-self: start;
}

.projectHeader__actionButtonsContainer {
	grid-area: projectHeader_actionButtonsContainer;
	display: flex;
	justify-content: flex-end;
	align-items: center;
	gap: var(--gap-tile);
}

:root[data-viewport="phone"] .projectHeader__view {
	padding-left: var(--pad-shell);
}

/**
* teamMemberPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-16 Mobile block converted from width media query to the `data-mobile` axis (#1637)
* @version 2026-July-17 Phone rules re-gated :root[data-mobile] → :root[data-viewport="phone"] (decision 0004 phase 1, #1684)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.teamMemberPanel__view {
	height: 100%;
	min-width: 0;
	display: grid;
	grid-template-rows: auto auto minmax(0, 1fr);
	gap: var(--gap-tile);
}

/* Identity header (mirrors ClientPanel): round initials avatar spanning both rows,
 * display name + action icons on top, roles description below. */
.teamMemberPanel__header {
	display: grid;
	gap: var(--gap-inline) var(--gap-tile);
	align-items: center;
	grid-template-areas:
		'teamMemberPanel_initialsRoundHeading teamMemberPanel_displayName  teamMemberPanel_actionButtonsContainer'
		'teamMemberPanel_initialsRoundHeading teamMemberPanel_description  .';
	grid-template-columns: auto minmax(0, 1fr) auto;
	min-width: 0;
}

.teamMemberPanel__initialsRoundHeading {
	grid-area: teamMemberPanel_initialsRoundHeading;
}

.teamMemberPanel__displayName {
	grid-area: teamMemberPanel_displayName;
	text-align: left;
	color: var(--text-primary);
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.teamMemberPanel__description {
	grid-area: teamMemberPanel_description;
}

.teamMemberPanel__actionButtonsContainer {
	grid-area: teamMemberPanel_actionButtonsContainer;
	display: flex;
	justify-content: flex-end;
	align-items: center;
	gap: var(--gap-tile);
}

.teamMemberPanel__deleteButton {}

/* Section tab bar row (mirrors ClientPanel's tab-header rail). */
.teamMemberPanel__tabHeader {
	display: flex;
	align-items: center;
	gap: var(--gap-tile);
}

.teamMemberPanel__sectionTabs {
	min-width: 0;
	overflow-x: auto;
}

.teamMemberPanel__tabView {
	padding: var(--pad-card);
	height: 100%;
	overflow: auto;
}

.teamMemberPanel__performanceView {
	display: grid;
	gap: var(--gap-tile);
}

/* Mobile: gated on the `data-viewport="phone"` band (JS-synced
   from PHONE_MAX_PX), never a width media query — see decisions/0004. */
:root[data-viewport="phone"] .teamMemberPanel__view {
	margin: var(--gap-tile);
}

:root[data-viewport="phone"] .teamMemberPanel__header {
	padding: var(--pad-card);
	grid-template-areas:
		'teamMemberPanel_initialsRoundHeading teamMemberPanel_displayName            teamMemberPanel_actionButtonsContainer'
		'teamMemberPanel_description          teamMemberPanel_description            teamMemberPanel_description';
	grid-template-columns: auto minmax(0, 1fr) auto;
}

:root[data-viewport="phone"] .teamMemberPanel__tabView {
	padding: var(--pad-card);
}

/**
* compensation.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the edit button always (#1641)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.compensationView__view {
    position: relative;
    display: block;
    margin: var(--gap-stack);
}

.compensationView__viewContainer {
    position: relative;
}

.compensationView__view--edit {
    display: grid;
    grid-template-areas: '. compensationView__backgroundToggleBar compensationView__backgroundToggleBar compensationView__backgroundToggleBar' 'compensationView__dollarSign compensationView__rate compensationView__rate compensationView__buttonContainer';
    grid-template-columns: 1rem 1fr;
    grid-gap: 0.5rem;
}

.compensationView__backgroundToggleBar {
    grid-area: compensationView__backgroundToggleBar;
    width: 100%;
}

.compensationView__dollarSign {
    grid-area: compensationView__dollarSign;
}

.compensationView__rate {
    grid-area: compensationView__rate;
}

.compensationView__buttonContainer {
    grid-area: compensationView__buttonContainer;
    margin-left: auto;
}

.compensationView__cancelButton {
    margin-right: var(--gap-stack);
}

.compensationView__editButton {
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(50%, -50%);
    cursor: pointer;
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the edit button behind it — touch devices see it always. */
@media (hover: hover) {
    .compensationView__editButton {
        opacity: 0;
    }

    .compensationView__view:hover .compensationView__editButton {
        opacity: 1;
    }
}
/**
* timeLimitTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-03-23 Initial Version
* @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the edit button always (#1641)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
*/

.timeLimitTile__view {
    position: relative;
}

.timeLimitTile__editButton {
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(50%, -50%);
    cursor: pointer;
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the edit button behind it — touch devices see it always. */
@media (hover: hover) {
    .timeLimitTile__editButton {
        opacity: 0;
    }

    .timeLimitTile__view:hover .timeLimitTile__editButton {
        opacity: 1;
    }
}

.timeLimitTile__infinitySymbol {
    font-size: var(--font-size-stat);
    height: 1rem;
    transform: translateY(-1rem);
}
.timeLimitTile__controllers{
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: flex-end;
    gap: var(--gap-inline);
}
/**
* textEditOptionPicker.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing literals onto the role-token ladder; three dead/invalid declarations removed
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
*/

.textEditOptionPicker__view {
    display: grid;
    grid-template-areas: 'textEditOptionPicker__boldIcon textEditOptionPicker__bulletsIcon textEditOptionPicker__italicIcon textEditOptionPicker__underlineIcon textEditOptionPicker__codeIcon'
        'textEditOptionPicker__iframe textEditOptionPicker__iframe textEditOptionPicker__iframe textEditOptionPicker__iframe textEditOptionPicker__iframe';
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    gap: var(--gap-tile);
    margin: var(--gap-inline);
    height: calc(100dvh - 150px);
}

.textEditOptionPicker__boldIcon {
    grid-area: textEditOptionPicker__boldIcon;
    height: 2rem;
    width: 2rem;
    margin: auto 0 auto auto;
}

.textEditOptionPicker__bulletsIcon {
    grid-area: textEditOptionPicker__bulletsIcon;
    height: 2rem;
    width: 2rem;
    margin: auto;
}

.textEditOptionPicker__italicIcon {
    grid-area: textEditOptionPicker__italicIcon;
    margin: auto;

}

.textEditOptionPicker__underlineIcon {
    grid-area: textEditOptionPicker__underlineIcon;
    margin: auto;

}

.textEditOptionPicker__insertImageIcon {
    grid-area: textEditOptionPicker__insertImageIcon;
    margin: auto;

}

.textEditOptionPicker__codeIcon {
    grid-area: textEditOptionPicker__codeIcon;
    margin: auto;

}

.textEditOptionPicker__boldButtonContainer {
    grid-area: textEditOptionPicker__boldButtonContainer;
    margin-left: auto;
}

.textEditOptionPicker__iframe {
    grid-area: textEditOptionPicker__iframe;
    overflow: scroll;
    border: 1px solid var(--border-default);
    border-radius: var(--radius-button);
    padding: var(--pad-dense) var(--pad-dense) var(--pad-card);
    margin: 0;
}

.textEditOptionPicker__unorderedListButtonButtonContainer {
    grid-area: textEditOptionPicker__unorderedListButtonButtonContainer;
}

.textEditOptionPicker__button-selected {
    fill: var(--brand-accent);
}

.textEditOptionPicker__icons {
    fill: inherit;
}
/**
* notePanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing and type literals onto the role-token ladder; two dead/invalid declarations removed
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
*/

.notePanel__view {
    display: block;
    margin: var(--gap-tile);
    border-radius: var(--radius-button);
    height: 100%;
    width: 50vw;
}

.notePanel__titleContainer {
    display: flex;
}

.notePanel__title {
    font-size: var(--font-size-stat);
    white-space: normal;
    max-height: 18rem;
    overflow: scroll;
}

.notePanel__content {
    overflow: scroll;
    width: 50vw;
    border: 1px solid var(--border-default);
    border-radius: var(--radius-button);
    padding: var(--pad-dense) var(--pad-dense) var(--pad-card);
    margin: 0;
    min-height: 10rem;
    cursor: text;
    max-height: calc(100dvh - 35rem);
    list-style-position: inside;
}
/**
* noteTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the delete button always (#1641)
* @version 2026-July-29 Spacing/type literals migrated onto the token contract's §Dense rungs — row chrome holds or tightens
*/

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

.noteTile__view {
    display: grid;
    grid-template-areas: 'noteTile__title noteTile__deleteButton' 'noteTile__date noteTile__deleteButton';
    grid-template-columns: 17rem;
    height: 6rem;
    margin-right: var(--gap-tile);
    margin-top: var(--gap-tile);
    padding: var(--pad-cell);
    cursor: pointer;
    border-radius: var(--radius-dense);
}

.noteTile__title {
    grid-area: noteTile__title;
    margin-right: auto;
    width: 100%;
    text-align: start;
}

.noteTile__date {
    grid-area: noteTile__date;
}

.noteTile__deleteButton {
    grid-area: noteTile__deleteButton;
    /* background-image: url('../../img/pngs/delete.png'); */
    height: 2rem;
    width: 2rem;
    margin: auto;
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the delete button behind it — touch devices see it always. */
@media (hover: hover) {
    .noteTile__deleteButton {
        opacity: 0;
    }

    .noteTile__view:hover .noteTile__deleteButton {
        /* background-color: var(--surface-sunken); */
        opacity: 1;
    }
}

.noteTile__view-selected {
    /* background-color: var(--surface-sunken); */
    border-color: var(--brand-accent);
}
/**
 * entityBox.css
 * @author Eduardo Valladares <eduardo.valladares@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2026-Jun-22 Deep-theming Phase 7: de-baked from the `-${theme}` class suffixes to one
 *                      stable structure painting from tokens; cyber restyles via the token layer
 *                      under [data-theme="cyber"] (no per-theme DOM).
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 * @version 2026-August-04 Swept the rules left dead by the strip to an identity-only card: the status
 *                      row, the action-button group, the temporary theme switcher and the edit dialog
 *                      frame (#1771). Hover cursor now comes from .tileContainer-hover.
 */

.entityBox__view {
	height: fit-content;
	display: grid;
	grid-template-rows: auto auto 1fr;
	padding: 0;
	overflow: hidden;
}

.entityBox__infoContainer {
	background-color: var(--surface-raised);
	display: grid;
	grid-template-areas:
		'entityBox_image  entityBox_role'
		'entityBox_displayName entityBox_displayName'
		'entityBox_type entityBox_type';
	padding: var(--pad-card);
	border-radius: var(--radius-button) var(--radius-button) 0 0;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: var(--gap-inline);
	position: relative;
	isolation: isolate;
}

.entityBox__infoContainer::before {
	content: '';
	position: absolute;
	inset: auto 0 0 0;
	height: 100%;
	background: linear-gradient(to top, var(--surface-card) 50%, transparent 65%);
	opacity: 0.75;
	pointer-events: none;
	z-index: -1;
}

.entityBox__image {
	grid-area: entityBox_image;
}

.entityBox__displayName {
	grid-area: entityBox_displayName;
}

.entityBox__role {
	height: fit-content;
	width: auto;
	max-width: 100%;
	grid-area: entityBox_role;
	justify-self: end;
	border: var(--border-shorthand);
	border-radius: var(--radius-card);
	padding: 0 var(--pad-card);
	display: flex;
	align-items: center;
	background-color: var(--brand-accent);
}

.entityBox__type {
	grid-area: entityBox_type;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}
/**
* personalInfo.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
*/

.personalInfo__view {
    height: auto;
    display: block;
    width: 100%;
}

.personalInfo__displayInfoContainer {
    display: grid;
    grid-template-areas: 'personalInfo_name personalInfo_email' 'personalInfo_tel personalInfo_address' 'personalInfo_cancelButton personalInfo_editButton';
    grid-gap: 7rem;
    grid-template-columns: 1fr 1fr;
}

.personalInfo__name {
    display: grid;
    grid-area: personalInfo_name;
}
.personalInfo__nameTitle{
    border: 1px solid var(--brand-accent);
}
.personalInfo__fullNameString{
    margin: auto;

}
.personalInfo__email {
    grid-area: personalInfo_email;
    display: grid;

}
.personalInfo__emailTitle{
    border: 1px solid var(--brand-accent);
}
.personalInfo__emailString{
    margin: auto;

}
.personalInfo__tel {
    grid-area: personalInfo_tel;
    display: grid;

}
.personalInfo__telTitle{
    border: 1px solid var(--brand-accent);
}
.personalInfo__telephoneString{
    margin: auto;

}
.personalInfo__address {
    grid-area: personalInfo_address;
    display: grid;

}
.personalInfo__addressTitle{
    border: 1px solid var(--brand-accent);
}
.personalInfo__addressString{
    margin: auto;

}
.personalInfo__editButton {
    grid-area: personalInfo_editButton;
}

.personalInfo__displayEditContainer {
    display: grid;
    grid-template-areas: 'personalInfo_editName personalInfo_editEmail' 'personalInfo_editTel personalInfo_editAddress' 'personalInfo_cancelButton personalInfo_commitButton';
    grid-template-columns: 1fr 1fr;
    grid-gap: 1rem;
}

.personalInfo__editName {
    grid-area: personalInfo_editName;
}

.personalInfo__editName-title{
    border: 1px solid var(--brand-accent);   
}

.personalInfo__editEmail {
    grid-area: personalInfo_editEmail;
}

.personalInfo__editEmail-title{
    border: 1px solid var(--brand-accent);   
}
.personalInfo__editTel {
    grid-area: personalInfo_editTel;
}

.personalInfo__editTel-title{
    border: 1px solid var(--brand-accent);   
}
.personalInfo__editAddress {
    grid-area: personalInfo_editAddress;
}

.personalInfo__editAddress-title{
    border: 1px solid var(--brand-accent);   
}
.personalInfo__cancelButton {
    grid-area: personalInfo_cancelButton;
}
.personalInfo__commitButton {
    grid-area: personalInfo_commitButton;
}
/**
* companyNameField.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
*/


/**
* contactPillBox.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
*/

.contactPillBox__view {
    height: 15rem;
    width: 20rem;
    display: grid;
    grid-template-areas: 'contactPillBox__topContainer' 'contactPillBox__bottomContainer';
}

.contactPillBox__topContainer {
    grid-area: contactPillBox__topContainer;
    display: grid;
    grid-template-areas: 'contact__image' 'contactPillBox__displayName';
}

.contact__image {
    grid-area: contact__image;
    margin: auto;
}

.contactPillBox__displayName {
    grid-area: contactPillBox__displayName;
}

.contactPillBox__bottomContainer {
    grid-area: contactPillBox__bottomContainer;
    display: grid;
    grid-template-areas: 'contactPillBox__visitContact contactPillBox__deleteContact';
}

.contactPillBox__visitContact {
    grid-area: contactPillBox__visitContact;
    height: 3rem;
    width: 3rem;
    margin: auto;
}

.contactPillBox__deleteContact {
    grid-area: contactPillBox__deleteContact;
    margin: auto;
}
/**
* entitiesPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.entitiesPanel__view {
    display: grid;
    grid-template-areas: 'entitiesPanel__searchBar' 'entitiesPanel__scrollArea';
    height: 100%;
}

.entitiesPanel__searchBar {
    grid-area: entitiesPanel__searchBar;
    margin-right: auto;
    width: 100%;
}

.entitiesPanel__scrollAreaContainer {
    grid-area: entitiesPanel__scrollArea;
    overflow: scroll;
    display: flex;
}

.entitiesPanel__scrollArea {
    height: fit-content;
    display: block;
}

.entitiesPanel__showAllEntityTile {
    width: fit-content;
    margin: var(--gap-stack) var(--gap-stack) var(--gap-stack) 4.5rem; /* intentional literal: the 4.5rem is a rail-aligned indent, not a density step */
    cursor: pointer;
}

.entitiesPanel__entityTile {
    margin: var(--gap-stack);
}
/**
* entityMembersPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.entityMembersPanel__view {
    height: 19rem;
    display: grid;
    grid-template-areas: 'entityMembersPanel__leftContainer entityMembersPanel__rightContainer';
    grid-template-columns: 1fr 1fr;
    gap: var(--gap-tile);
}

.entityMembersPanel__leftContainer {
    grid-area: entityMembersPanel__leftContainer;
}

.entityMembersPanel__membersHeading {}

.entityMembersPanel__membersSearchBar {
    margin: var(--gap-stack);
}

.entityMembersPanel__membersScrollArea {}

.entityMembersPanel__rightContainer {
    grid-area: entityMembersPanel__rightContainer;
}

.entityMembersPanel__entitiesHeading {}

.entityMembersPanel__entitiesSearchBar {
    margin: var(--gap-stack);
}

.entityMembersPanel__entitiesScrollArea {
    height: 13rem;
}
.entityMemberPanel__entityTile{
    margin: var(--gap-dense);
}

.entityMemberPanel__selfEntityTile {
    /* pointer-events: none; */
}
/**
* entityMemberChooser.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
*/

.entityMemberChooser__entityMembersFloatingPanel{
    backdrop-filter: var(--surface-blur);
}
.entityMemberChooser__entitiesDisplayImageContainer{
    display: flex;
    flex-wrap: wrap;
}

/**
* headerWithExpandableScrollArea.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2022-02-24 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.headerWithExpandableScrollArea__view {
    display: grid;
    width: 100%;
    height: 100%;
}

.headerWithExpandableScrollArea__headerContainer {
    width: 50%;
    margin: auto auto auto 0;
    /* The 0 bottom is deliberate — the expandable scroll area below supplies its own. */
    padding: var(--pad-row) var(--pad-row) 0 var(--pad-row);
}

.headerWithExpandableScrollArea__header {
    text-align: left;
}

.headerWithExpandableScrollArea__scrollAreaContainer {
    max-height: 0;
    overflow: hidden;
}

.headerWithExpandableScrollArea__scrollAreaContainer-expanded {
    max-height: inherit;
}

.headerWithExpandableScrollArea__scrollArea {
    padding: var(--pad-row);
}
/**
 * projectEntryTile.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2019-03-19 Initial Version
 * @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the edit button always (#1641)
 */

.projectEntryTile__view {
	width: auto;
	display: grid;
	grid-template-columns: 1fr auto;
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the edit button behind it — touch devices see it always. */
@media (hover: hover) {
	.projectEntryTile__view:hover .projectEntryTile__editButton {
		opacity: 1;
	}

	/* The transition belongs on the base rule, not the `:hover` rule — declared
	   on `:hover` it only existed while hovered, so the reveal faded in and then
	   snapped out on exit. */
	.projectEntryTile__editButton {
		opacity: 0;
		transition: all var(--motion-fast) var(--ease-enter);
	}
}

.projectEntryTile__projectDescription {
	grid-column: 1/1;
	font-weight: bold;
}

.projectEntryTile__total {
	grid-column: 1/2;
}

.projectEntryTile__project {
	grid-column: 2/1;
}

.projectEntryTile__editButton {
	grid-column: 2/2;
	justify-self: end;
	cursor: pointer;
}
/**
* mainSearchBar.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2022-May-25 Initial Version
*/

.mainSearchBar__view {
	/* background-image: url('../../../assets/icons/searchbar.svg');
    background-size: cover;
    background-repeat: no-repeat;
    height: 5rem;
    width: 20rem; */
	position: relative;
	width: 25rem;
	height: 2.6rem;
}

.mainSearchBar__view::before {
	content: '';
	background-color: var(--brand-primary);
	position: absolute;
	right: 0;
	top: 0;
	width: 5rem;
	height: 2rem;
	clip-path: polygon(calc(100% - 1.5rem) 100%, 100% 0, 1.1rem 0, 1.1rem .1rem, calc(100% - 0.2rem) .1rem, calc(100% - 1.6rem) 100%);
}

.mainSearchBar__view::after {
	content: '';
	background-color: var(--brand-accent);
	position: absolute;
	left: 0;
	bottom: 0;
	width: 4rem;
	height: 1.5rem;
	clip-path: polygon(0 100%, 100% 100%, 100% calc(100% - .1rem), 0.15rem calc(100% - .1rem), 1.2rem 0, 1.1rem 0);
}

.mainSearchBar__background {
	color: var(--brand-accent);
}

.mainSearchBar__input {
	width: calc(100% - 5.1rem);
	height: 2rem;
	border: none;
	background-color: var(--surface-sunken);
	color: var(--text-primary);
	border-radius: 0;
	clip-path: polygon(0 100%, calc(100% - 1.5rem) 100%, 100% 0, 1.5rem 0);
	padding: 0.3rem 2rem; /* intentional literal: geometry-coupled to the clip-path parallelogram on this rule — the 2rem keeps text clear of the diagonals */
	position: absolute;
	bottom: .3rem;
	right: 4.4rem;
}

.mainSearchBar__input::placeholder {
	color: var(--text-secondary);
}

.mainSearchBar__button {
	background-color: var(--brand-primary);
	position: absolute;
	right: 1rem;
	width: 4.5rem;
	height: 2rem;
	clip-path: polygon(0 100%, calc(100% - 1.5rem) 100%, 100% 0, 1.5rem 0);
	display: inline-flex;
	bottom: .3rem;
	cursor: pointer;
}

.mainSearchBar__icon {
	margin: auto;
	fill: var(--text-on-brand);
}

:root[data-viewport="phone"] .mainSearchBar__view {
	height: var(--touch-target-primary);
	width: 20rem;
}

:root[data-viewport="phone"] .mainSearchBar__view::before {
	height: 3rem;
}

:root[data-viewport="phone"] .mainSearchBar__view::after {
	height: 2.5rem;
}

:root[data-viewport="phone"] .mainSearchBar__input,
:root[data-viewport="phone"] .mainSearchBar__button {
	height: var(--touch-target-primary);
	bottom: 0;
}

:root[data-viewport="phone"] .mainSearchBar__button {
	min-width: var(--touch-target-primary);
}

/**
* navigationRail.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2022-May-25 Initial Version (as settingsBar.css)
* @version 2026-May-20 Renamed: settingsBar → navigationRail (Material's industry-standard name for this pattern)
* @version 2026-July-17 Phone rules re-gated :root[data-mobile] → :root[data-viewport="phone"] (decision 0004 phase 1, #1684)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
* @version 2026-August-03 Collapsed-pill geometry (#1764): drop the desktop 28rem cap so
*   the pill is content-driven; hide the displayPanel at rest (height:0, opacity:0,
*   visibility:hidden — removes the close button from the tab order) and reveal it on
*   .navigationRail__mainPanel-expanded; hover-expand cap widened 16rem → 30rem.
*/
.navigationRail__view {
	height: fit-content;
	width: fit-content;
}

.navigationRail__mainPanel__optionsPanel {
	height: fit-content;
	display: grid;
	gap: var(--gap-tile);
	justify-content: flex-start;
	align-content: start;
	align-items: start;
	padding-right: var(--pad-card);
}

/* Both bottom-of-rail selectors share the same left-alignment so they line up. */
.navigationRail__colorSchemeSelector,
.navigationRail__depthSelector {
	margin-left: var(--gap-tight);
	justify-self: start;
}

.navigationRail__mainPanel__displayPanel {
	display: grid;
	grid-template-rows: auto 1fr;
	padding: 0 var(--pad-card);
	width: 50dvw;
	height: 0;
	opacity: 0;
	visibility: hidden;
	/* pulls the panel's close <button> out of the tab order while collapsed */
}

/* deep-theming: single stable structure; cyber restyles via tokens under [data-theme] */
.navigationRail__mainPanel {
	display: grid;
	grid-template-columns: 1fr 0;
	padding: var(--pad-card) 0;
	position: absolute;
	z-index: 2;
	max-width: 4rem;
	overflow: hidden;
}

/* Hover-affordance audit #11 (#1641): hover-to-expand is a hover-capable-only
   affordance — on touch it only causes sticky-hover jank (the tap's synthetic
   hover expands the rail under the finger). Touch operability is already fully
   covered by the click path: every option is clickable collapsed and
   displayExpandedView() is the click-to-expand. */
@media (hover: hover) {
	.navigationRail__mainPanel:not(.navigationRail__mainPanel-expanded):hover {
		max-width: 30rem;
		padding-left: var(--pad-card);
	}
}

.navigationRail__mainPanel.navigationRail__mainPanel-expanded {
	padding-left: var(--pad-card);
	grid-template-columns: 1fr auto;
	max-width: 100dvw;
	max-height: 100dvh;

	.navigationRail__mainPanel__displayPanel {
		height: 50dvh;
		opacity: 1;
		visibility: visible;
	}
}

.navigationRail__mainPanel__option {
	padding: 0 var(--pad-dense);
	align-items: center;
	cursor: pointer;
	width: 100%;
	box-shadow: var(--elevation-flat);
}

.navigationRail__mainPanel__option:not(.navigationRail__mainPanel__option-active):hover {
	background-color: var(--surface-hover);
}

.navigationRail__mainPanel__option-active {
	background-color: var(--brand-accent);
	color: var(--text-on-brand);
}

.navigationRail__mainPanel__option-active .navigationRail__mainPanel__option__heading {
	color: var(--text-on-brand);
}

.navigationRail__controllerContainer {
	display: flex;
	justify-content: space-between;
}

:root[data-viewport="phone"] .navigationRail__mainPanel__option {
	min-height: var(--touch-target-primary);
}

:root[data-viewport="phone"] .navigationRail__mainPanel {
	max-height: 100dvh;
}

/* #endregion */

/**
* onlineIndicator.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2022-September-27 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-August-14 Dot + glow read --status-danger; the raw rgb(255,0,15) was theme-blind (#1840)
*/

.onlineIndicator__view {
    display: grid;
    height: fit-content;
    /* width: 1rem; */
    width: fit-content;
    /* grid-template-areas: 'onlineIndicator_header onlineIndicator_header'
        'onlineIndicator_circle onlineIndicator_square'; */
        grid-template-areas: '. onlineIndicator_header'
        'onlineIndicator_circle onlineIndicator_square';
    /* row-gap: 3.5rem; */
    row-gap: .2rem; /* intentional literal: 2px decorative nudge — below the 4px ladder floor */
    column-gap: var(--gap-inline);
    align-items: center;
}

.onlineIndicator__header {
    grid-area: onlineIndicator_header;
    color: var(--text-secondary);
    /* transform: rotate(-90deg); */
    letter-spacing: .5rem;
    height: fit-content;
    width: fit-content;
    text-shadow: 0 0 1px var(--text-secondary);
    writing-mode: vertical-lr;
    scale: -1;
}

.onlineIndicator__circle {
    grid-area: onlineIndicator_circle;
    background-color: var(--status-danger);
    width: .4rem;
    height: .4rem;
    border-radius: var(--radius-shell);
    box-shadow: 0 0 3px 1px var(--status-danger); /* intentional literal: the 3px/1px glow geometry, not an elevation — --elevation-glow is brand-accent tinted */
    justify-self: end;
    margin-right: .2rem; /* intentional literal: 2px decorative nudge — below the 4px ladder floor */
}

.onlineIndicator__square {
    grid-area: onlineIndicator_square;
    background-color: var(--text-secondary);
    width: 1rem;
    height: 1rem;
    border-radius: var(--radius-dense);
    /* margin: auto 1rem auto 0; */
    box-shadow: 0 0 3px 1px var(--text-secondary); /* intentional literal: coloured glow, not an elevation */
}
/**
* menuTabButton.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.menuTabButton__view {
    margin: 2rem 4rem; /* intentional literal: page-header offset — no role token above 24px */
    height: 6rem;
    display: grid;
}

.menuTabButton__pillbox {
    border-color: currentColor;
    height: 6rem;
    border-radius: unset;
    cursor: pointer;
    display: flex;
    /* color: var(--grey); */
    color: var(--text-primary);
    /* clip-path: polygon(0 0, calc(100% - 10px) 0, calc(100% - 0px) 10px, 100% 20.00px, 100% 100%, 0 100%) */
}

.menuTabButton__pillbox--active {
    border-color: var(--brand-accent);
    color: var(--brand-accent);
}



.menuTabButton__pillbox:before {
    /* background: var(--brand-accent); */
    /* background: var(--surface-sunken); */
    /* height: 2.4rem;
    width: 0.1rem;
    right: 0.6rem;
    top: -0.96rem; */
    /* background: currentColor; */
}

.menuTabButton__heading {
    margin-left: var(--gap-stack);
    /* color: var(--grey); */
    color: var(--text-primary);
}

.menuTabButton__heading--active {
    color: var(--brand-accent);
}

.menuTabButton__subTabsContainer {
    /* position: relative; */
    /* clip-path: polygon(0 0, calc(100% - 20.00px) 0, calc(100% - 10px) 10px, 100% 20.00px, 100% 100%, 0 100%); */
    display: grid;
    gap: var(--gap-section);
    justify-content: flex-start;
    margin: var(--gap-section);

}
/**
* subTabButton.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
* @version 2026-August-14 Idle bullet reads --text-disabled — white on an unbacked menu surface was invisible in light mode (#1840)
*/

.subTabButton__view {
	display: grid;
	grid-template-areas: 'subTabButton_circle subTabButton_heading';
	width: fit-content;
	gap: var(--gap-stack);
}

.subTabButton__circle {
	grid-area: subTabButton_circle;
	background-color: var(--text-disabled);
	width: .5rem;
	height: .5rem;
	border-radius: var(--radius-shell);
	margin: auto;

	.subTabButton__view:hover & {
		background-color: var(--brand-accent);
	}
}

.subTabButton__circle--active {
	background-color: var(--brand-accent);
}

.subTabButton__heading {
	grid-area: subTabButton_heading;
	cursor: pointer;

	.subTabButton__view:hover & {
		color: var(--brand-accent);
	}
}

.subTabButton__heading--active {
	color: var(--brand-accent);
}

/**
* customizeThemePanel.css
* @author Miguel A. González <miguel.gonzalez@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-24 Initial Version (#1006)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.customizeThemePanel__view {
    display: flex;
    flex-direction: column;
    gap: var(--gap-stack);
    padding: var(--pad-sheet);
    min-width: 24rem;
    max-width: 32rem;
    color: var(--text-primary);
    background: var(--surface-page);
    border-radius: var(--radius-card);
    backdrop-filter: var(--surface-blur);
}

.customizeThemePanel__heading {
    margin: 0;
}

.customizeThemePanel__note {
    font-size: var(--font-size-label);
    color: var(--text-secondary);
    line-height: 1.4;
}

.customizeThemePanel__createForm {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--gap-dense) var(--gap-stack);
    align-items: center;
}

.customizeThemePanel__fieldLabel {
    font-weight: 500;
}

.customizeThemePanel__nameInput {
    padding: var(--pad-input) var(--pad-input-inline);
    background: var(--surface-card);
    color: var(--text-primary);
    border: none;
    border-radius: var(--radius-button);
    font: inherit;
}

.customizeThemePanel__error {
    color: var(--brand-accent);
    font-size: var(--font-size-label);
}

.customizeThemePanel__buttonRow {
    display: flex;
    justify-content: flex-end;
    gap: var(--gap-dense);
    margin-top: var(--gap-dense);
}

.customizeThemePanel__targetSection {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--gap-stack);
    align-items: center;
}

.customizeThemePanel__previewRow {
    display: flex;
    justify-content: flex-end;
    padding: var(--pad-dense) 0;
}

.customizeThemePanel__tiles {
    display: flex;
    flex-direction: column;
    gap: var(--gap-dense);
    max-height: 24rem;
    overflow-y: auto;
    padding-right: var(--pad-dense);
}

.customizeThemePanel__tileRow {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--gap-inline);
    align-items: center;
}

.customizeThemePanel__tilesLoading {
    min-height: 6rem;
}

.customizeThemePanel__tileReset {
    font-size: var(--font-size-label);
    padding: var(--pad-cell) var(--pad-dense);
}

/**
 * addTeamMemberPanel.css
 * @author Eduardo Valladares <eduardo.valladares@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2022-Oct-19 Initial Version
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 */

.addTeamMemberPanel__view {
	/* width: calc(100% - 55rem);
	height: calc(100% - 45rem); */
	margin: 10rem auto; /* intentional literal: dialog top offset — positioning, not density; no role token above 24px */
	display: grid;
	grid-template-areas: 'addTeamMemberPanel_closeButton addTeamMemberPanel_searchBar' 'addTeamMemberPanel_scrollArea addTeamMemberPanel_scrollArea';
	grid-template-rows: auto minmax(0, 1fr);
	row-gap: var(--gap-stack);
	overflow: hidden;
}

.addTeamMemberPanel__closeButton {
	grid-area: addTeamMemberPanel_closeButton;
}

.addTeamMemberPanel__searchBar {
	grid-area: addTeamMemberPanel_searchBar;
	margin: auto var(--gap-stack) auto auto;
}

.addTeamMemberPanel__scrollArea {
	grid-area: addTeamMemberPanel_scrollArea;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--gap-tile);
}

.addTeamMemberPanel__closeButton {
	transform: rotate(180deg);
}
/**
 * teamMemberPerformance.css
 * @author Eduardo Valladares <eduardo.valladares@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2022-Nov-03 Initial Version 
 */

/**
* addressFields.css
* @author John A Cruz Merced <john.cruz@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-March-24 Initial Version
* @version 2026-July-03 Grid moved from the form to the new fieldset wrapper (#731)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

/* The form's only child is the fieldset (getFieldset resets the UA chrome via
   `.fieldset`), so the 6-column grid rides the fieldset now. The hidden legend
   is position:absolute (.visuallyHidden) — it never occupies a grid cell. */
.addressFields__fieldset {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: var(--gap-stack);
}

.addressFields__lineInput {
	grid-column: 1 / -1;
}

.addressFields__dropdown {
	width: 100%;
	grid-column: span 2
}

.addressFields__postalInput {
	grid-column: span 3;
}

.addressFields__removeButton {
	align-self: center;
}

.addressFields__addressType {
	grid-column: -3 / -1;
}
/**
* emailFields.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
*/


/**
* telephoneFields.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
*/

.telephoneFields__view {
	display: grid;
	grid-template-areas: 'cCode aCode pre post';
	grid-template-columns: 2.5rem 3rem repeat(2, 1fr);
	column-gap: var(--gap-inline);
}

.telephone__view {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
	gap: var(--gap-inline);

	>* {
		width: auto;
	}
}
/**
* dynamicInput.css
* @author Jorge Pacheco <jorge.pacheco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2023-January-24 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder
* @version 2026-August-14 Phone-band floating label one rung up — the measurement proxy moves WITH it (it drives the frame's notch clip-path)
* @version 2026-August-14 .textInput__errorText — the inline field error, parked under the control so it never reflows the row
*/

.textInput__view {
	display: flex;
	align-items: center;
	box-sizing: border-box;
	min-height: 2.5rem;
	position: relative;
	width: 100%;
	background: var(--surface-sunken);
	border-radius: var(--radius-input);
}

.textInput__container {
	width: 100%;
	/* height: calc(100% - 1rem); */
	height: 100%;
	border-radius: var(--radius-card);
	border-color: inherit;
	position: relative;
}

.textInput__frame {
	position: absolute;
	inset: 0;
	border: var(--border-shorthand);
	border-radius: var(--radius-input);
	width: 100%;
	height: 100%;
	pointer-events: none;
	transition: clip-path .5s .2s;
}

.textInput__frame-open {
	transition: clip-path .5s 0s;
}

.textInput__view:has(.textInput__input:focus-visible) {
	outline: var(--focus-ring-width) solid var(--focus-ring-color);
	outline-offset: var(--focus-ring-offset);
}

.textInput__input {
	border: none;
	height: 100%;
	width: 100%;
	position: absolute;
	background: transparent;
	box-shadow: none;
	font-size: var(--font-size-body);
}

.textInput__input:not(:focus) {
	text-overflow: ellipsis;
}

.textInput__input:-webkit-autofill,
.textInput__input:-webkit-autofill:hover,
.textInput__input:-webkit-autofill:focus,
.textInput__input:-webkit-autofill:active {
	/* intentional literal: the canonical Chrome autofill-yellow suppression hack —
	   an absurd duration so the UA's background paint never actually arrives.
	   Not a motion value; do not put it on the --motion-* ladder. */
	transition: background-color 5000s ease-in-out 0s;
}

.textInput__placeholderNode {
	position: absolute;
	left: 1rem;
	top: 50%;
	translate: 0 -50%;
	transition: top .5s 0s, left .5s 0s, font-size .5s 0s, translate .5s 0s, width .5s 0s;
	line-height: 1.1;
	max-width: calc(100% - 1.2rem);
	width: calc(100% - 3rem);
	text-align: start;
	color: var(--text-secondary);
	overflow: hidden;
	display: flex;
	align-items: baseline;
	pointer-events: none;
}

.textInput__placeholderText {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	min-width: 0;
}

.textInput__placeholderNode-shrunk {
	top: 0;
	left: 1.5rem;
	font-size: var(--font-size-label);
	width: calc(100% - 3.5rem);
	transition: top .5s .4s, left .5s .4s, font-size .5s .4s, translate .5s .4s, width .5s .4s;
}

.textInput__placeholderNodeProxy {
	opacity: 0;
	position: fixed;
	font-size: var(--font-size-label);
}

.textInput__required {
	color: var(--status-danger);
	margin-left: var(--gap-hairline);
	flex: none;
}

.textInput__frame-error {
	border-color: var(--status-danger);
	animation: shake .1s linear;
}

.textInput__view-error {
	animation: shake .5s linear;
}

.textInput__errorText {
	position: absolute;
	top: 100%;
	left: var(--pad-dense);
	color: var(--status-danger);
	opacity: 1;
	text-align: left;
	font-style: normal;
}

.textInput__view-disabled {
	opacity: 0.4;
	pointer-events: none;
}

.textInput__input__upperCase {
	text-transform: uppercase;
}

:root[data-viewport="phone"] {
	.textInput__placeholderNode-shrunk,
	.textInput__placeholderNodeProxy {
		font-size: var(--font-size-caption);
	}
}

/**
* dropdownInputCollection.css
* @author John A Cruz Merced <john.cruz@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-March-25 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.dropdownInputCollection__view {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	grid-template-rows: auto minmax(0, 1fr);
}

.dropdownInputCollection__addButton {
	align-items: center;
	display: flex;
	gap: var(--gap-stack);
}

.dropdownInputCollection__uList {
	grid-column: 1 / -1;
	padding: var(--pad-dense) 0 var(--gap-stack);
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	list-style: none;

	.heading {
		text-align: start;
	}

	.dropdownInputCollection__item {
		border-radius: var(--radius-card);
		background-color: var(--surface-raised);
		padding: var(--pad-card);
		margin: 0;

		.dropdownInputCollection__form {
			display: grid;
			grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr);
			align-items: center;
			gap: var(--gap-stack);

			.dropdown__view {
				width: auto;
			}
		}
	}
}
/**
* addressCollection.css
* @author John A Cruz Merced <john.cruz@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-March-26 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.addressCollection__view {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	grid-template-rows: auto minmax(0, 1fr);
}

.addressCollection__heading {
	text-align: start;
}

.addressCollection__addButton {
	align-items: center;
	display: flex;
	gap: var(--gap-stack);
}

.addressCollection__uList {
	grid-column: 1 / -1;
	padding: var(--pad-dense) 0 var(--gap-stack);
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	list-style: none;

	.addressCollection__item {
		background-color: var(--surface-raised);
		border-radius: var(--radius-card);
		padding: var(--pad-card);
		margin: 0;
	}
}

/**
* clientEntityPreview.css
* @author John A Cruz Merced <john.cruz@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-March-31 Initial Version
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.clientEntityPreview__view {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
}

.clientEntityPreview__header {
	height: 10rem;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--gap-stack);
}

.clientEntityPreview__image {
	height: 75%;
	aspect-ratio: 1;
	min-width: auto;
	display: flex;
	border-radius: var(--radius-circle);
	background: var(--surface-sunken);
}

.clientEntityPreview__displayName {
	background: var(--surface-sunken);
}

/**
* editableDataBox.css
* @author Miguel A. González <miguel.gonzalez@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2023-February-27 Initial Version
* @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the edit button always (#1641). The .editableDataHeading__saveButton reveal is retained as-is inside the gate, but note it is currently dead: no JS applies that class (the save Icon gets no classes param)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*/

.editableDataHeading__view {
	width: auto;
	max-width: 100%;
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the edit button behind it — touch devices see it always. */
@media (hover: hover) {
	.editableDataHeading__view {
		&:hover .editableDataHeading__editButton {
			opacity: 1;
		}

		&:hover .editableDataHeading__saveButton:not([disabled]) {
			opacity: 1;
		}
	}

	.editableDataHeading__editButton {
		opacity: 0;
	}
}

.editableDataHeading__bodyContainer {
	width: fit-content;
	display: grid;
	grid-template-columns: auto auto;
	gap: var(--gap-inline);
	align-items: center;
}

.editableDataHeading__buttonsContainer {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
	width: 100%;
	max-width: 4rem;
	position: relative;
}
/**
* newEntityPanelPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-March-04 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
* @version 2026-August-04 The panel is a plain in-flow grid: the fixed/centered dialog positioning and the card surface moved OUT to the hosts, which supply them (EntitiesView wraps it in a `getPillBox`; EntityInfo swaps it in where its read-only fields were). No `-inline` rules live here — that class is a marker hosts may target, not a variant this sheet styles.
*/


.newEntityPanel__form {
	display: grid;
	grid-template-rows: auto auto auto minmax(0, 30rem) auto;
	gap: var(--gap-stack);
}

.newEntityPanel__heading {
	text-align: left;
}

.newEntityPanel__nameInputContainer {
	display: grid;
	gap: .5rem
}

.newEntityPanel__entityNameInput {
	/* text-align: center; */
}

.newEntityPanel__typeContainer {
	display: grid;
	padding-bottom: var(--pad-row);
	gap: .5rem
}

.newEntityPanel__entitiesTypeDropdown {
	width: 100%;
}

.newEntityPanel__contactsContainer {
	display: flex;
	flex-direction: column;
	gap: var(--gap-tile);
}

.newEntityPanel__contactsContainer:empty {
	display: none;
}

.newEntityPanel__buttonsContainer {
	display: flex;
	gap: var(--gap-tile);
	justify-content: end;
	padding-top: var(--pad-row);
}

.newEntityPanel__cancelButton,
.newEntityPanel__saveButton {
	width: 7rem;
}

:root[data-viewport="phone"] .newEntityPanel__view {
	width: 92vw;
}

/**
* newClientPanel.css
* @author John A Cruz Merced <john.cruz@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-March-20 Initial Version
* @version 2026-July-03 Drop the `-hidden` slide-behind rules — the suggestions pillbox is now
*                       DOM-gated in NewClientPanel.render() instead of CSS-concealed (#1207)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
* @version 2026-August-14 44px phone-band floor on the Save/Cancel pair (#1840) — the buttons carry
*                       no component class, so the container reaches them as a descendant selector
* @version 2026-August-21 (#1764 rework): the panel is bounded and its body scrolls. The suggestions
*                       drawer stays a `position: absolute; right: 0; height: 100%` overlay with a
*                       `-expanded` visibility modifier (`width: 0` base → `width: 50%` when a search
*                       has landed matches; `-expanded` also gates the phone `width: 100%; max-width:
*                       none` override). The bound: `.newClientPanel__view { height: 85dvh }` on the
*                       panel + `flex: 1 1 auto; min-height: 0` on the scroll area let the row
*                       flex's `align-items: stretch` bind `main`, and the scroll area absorbs
*                       overflow when picking an existing entity mounts the ClientEntityPreview in
*                       the form body. The three wrapper classes (`clientsView__newClientPanel`,
*                       `clientPanel__newClientPanel`, `newProjectPanel__newClientPanel`) dropped
*                       their `height: 75%` / phone `height: 100%` rules — they were shadowing the
*                       panel's own `height: 85dvh` at equal specificity and resolving to `auto`
*                       against the auto-height `.floatingPanel` anyway. Dead rules pruned in the
*                       same pass: the inert `.newClientPanel__customButton` grid-area now that
*                       the buttons row is flex, the auto-fill row template on an auto-height
*                       list, two phone overrides whose selectors were reworked
*                       (`.newClientPanel__main` grid → flex, `.newClientPanel__suggestedList`
*                       flex-wrap → grid), the inert `max-height: 100%` on
*                       `.newClientPanel__entityPreview` (percentage in an auto-height chain),
*                       and the provably-no-op `.clientEntityPreview__view` parent-CSS reach-in.
* @version 2026-August-22 (#1982) The phone width override moves onto the `-expanded` modifier —
*                       the selector this header always claimed. Unscoped, the collapsed drawer
*                       (base `width: 0`) went `width: 100%` on the phone band while staying the
*                       `position: absolute; height: 100%; top: 0` overlay, so an invisible
*                       full-panel card sat over Save/Cancel and every phone-band add-client
*                       journey failed `assertTappable` (nightly 2026-08-22, all three engines).
*/

.newClientPanel__view {
	position: relative;
	display: flex;
	width: 100%;
	height: 85dvh;

	.addressCollection__item,
	.dropdownInputCollection__item {
		padding: unset;
	}
}

.newClientPanel__main {
	flex: 1 1 0;
	min-width: 0;
	min-height: 0;
	display: flex;
	flex-direction: column;
	gap: var(--gap-tile);
}

.newClientPanel__header {
	justify-self: start;
}

.newClientPanel__nameInput {
	width: 100%;
}

.newClientPanel__buttonsContainer {
	justify-content: end;
	display: flex;
	gap: var(--gap-tile);
}

.newClientPanel__suggestionsPillbox {
	max-width: 40rem;
	width: 0;
	display: flex;
	overflow: hidden;
	flex-shrink: 0;
	position: absolute;
	height: 100%;
	top: 0;
	right: 0;
	padding: 0;
}

.newClientPanel__suggestionsPillbox-expanded {
	width: 50%;
	padding: var(--pad-card);
}

.newClientPanel__suggestionsSection {
	width: 100%;
	height: 100%;
	display: grid;
	grid-template-rows: auto minmax(0, 1fr) auto;
	gap: var(--gap-dense);
}

.newClientPanel__suggestedList {
	display: grid;
	gap: var(--gap-tile);
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	padding: var(--pad-card);
	width: auto;
	height: auto;

	>* {
		list-style-type: none;
		margin: 0;
	}
}

.newClientPanel__defaultEmailPicker {
	margin: 0 0 var(--gap-stack);
}

:root[data-viewport="phone"] .newClientPanel__view {
	width: 92vw;
	flex-direction: column;
	overflow-y: auto;
}

:root[data-viewport="phone"] .newClientPanel__suggestionsPillbox-expanded {
	width: 100%;
	max-width: none;
}

:root[data-viewport="phone"] .newClientPanel__suggestionsSection {
	border-top: var(--border-width) solid var(--border-default);
}

:root[data-viewport="phone"] .newClientPanel__suggestedList {
	width: 100%;
	height: fit-content;
}

.newClientPanel__customDetails {
	height: auto;
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
}

.newClientPanel__scrollArea {
	flex: 1 1 auto;
	min-height: 0;
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	padding: var(--pad-cell);
}

/**
* clientPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
*
*/

.clientPanel__view {
	height: 100%;
	display: grid;
	grid-template-rows: auto auto minmax(0, 1fr);
	gap: var(--gap-stack);
}

.clientPanel__header {
	display: grid;
	gap: var(--gap-dense) var(--gap-stack);
	align-items: center;
	grid-template-areas:
		'clientPanel_initialsRoundHeading clientPanel_displayName clientPanel_actionButtonsContainer'
		'clientPanel_initialsRoundHeading clientPanel_description .';
	grid-template-columns: auto 1fr auto;
}

.clientPanel__initialsRoundHeading {
	grid-area: clientPanel_initialsRoundHeading;
}

.clientPanel__displayName {
	grid-area: clientPanel_displayName;
	text-align: left;
	color: var(--text-primary);
}

.clientPanel__description {
	grid-area: clientPanel_description;
}

/* Section tab bar (mirrors the panel's tab-header rail). */
.clientPanel__tabHeader {
	display: flex;
	align-items: center;
	gap: var(--gap-stack);
}

.clientPanel__sectionTabs {
	min-width: 0;
	overflow-x: auto;
}

/* Status slider + action icons together in the header's top-right (mirrors ProjectHeader). */
.clientPanel__actionButtonsContainer {
	grid-area: clientPanel_actionButtonsContainer;
	display: flex;
	justify-content: flex-end;
	align-items: center;
	gap: var(--gap-stack);
}

.clientPanel__deleteButton {}

.clientPanel__editButton {}

/* First-load skeleton — mirrors the loaded container (header row + tab bar + list body). */
.clientPanel__headerSkeleton {
	padding: var(--pad-dense) 0;
}

.clientPanel__bodySkeleton {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	min-height: 0;
	overflow: hidden;
}

.clientPanel__tabView {
	height: 100%;
	overflow: auto;
}

.clientPanel__infoView {
	padding: var(--pad-card);
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	grid-template-rows: repeat(2, auto);
	gap: var(--gap-section);
}

.clientPanel__projectsView {
	display: block;
	height: 100%;
	padding: var(--pad-card);
}

.clientPanel__projectTile {
	margin: var(--gap-stack);
}

.clientPanel__projectTile-inactive {
	pointer-events: none;
	opacity: 0.5;
}

.clientPanel__invoicesView__view {
	padding: var(--pad-card);
	height: 100%;
}

.clientPanel__newInvoiceView {
	padding: var(--pad-shell);
}

.clientPanel__newClientPanel {
	width: 50%;
}

:root[data-viewport="phone"] .clientPanel__newClientPanel {
	width: 100%;
}

:root[data-viewport="phone"] .clientPanel__header {
	padding-left: var(--pad-shell);
}

.clientPanel__invoiceOverlayActions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--gap-dense) var(--gap-stack);
}

/**
* projectDeadlineSummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-April-08 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

/* Shared detail-card stack: icon+label header (bottom border) / large value / supporting row. */
.projectDeadlineSummary__view {
	display: grid;
	row-gap: var(--gap-stack);
	grid-template-rows: auto auto 1fr;
	padding: var(--pad-card);
}

/* Permission self-hide: removed from the flex row so siblings stretch to fill. */
.projectDeadlineSummary__view-hidden {
	display: none;
}

.projectDeadlineSummary__iconLabelContainer {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.projectDeadlineSummary__value {
	/* color is set inline per deadline proximity (getStopColor); no deadline / loading falls back to --text-primary. */
}

.projectDeadlineSummary__supporting {
	display: flex;
	justify-content: space-between;
	gap: var(--gap-inline);
}

/**
* projectDescription.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-01 Initial Version — Details description card (mirrors taskDescription.css)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.projectDescription__view {
	display: grid;
	grid-template-rows: auto 1fr;
	gap: var(--gap-inline);
	padding: var(--pad-card);
}

.projectDescription__heading {
	text-align: left;
}

.projectDescription__text {
	color: var(--text-secondary);
}

/**
* projectProgressSummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-April-08 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

/* Shared detail-card stack: icon+label header (bottom border) / large value / supporting (bar) row. */
.projectProgressSummary__view {
	display: grid;
	row-gap: var(--gap-stack);
	grid-template-rows: auto auto 1fr;
	padding: var(--pad-card);
}

.projectProgressSummary__iconLabelContainer {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.projectProgressSummary__percentageValue {
	text-align: right;
}

/* Value color by completion tier (set in render): muted at 0, accent in progress, green when done. */
.projectProgressSummary__percentageValue-empty { color: var(--text-secondary); }
.projectProgressSummary__percentageValue-inProgress { color: var(--brand-primary); }
.projectProgressSummary__percentageValue-complete { color: var(--status-success); }

/* Supporting row holds the progress bar below the value (user obs 1). */
.projectProgressSummary__supporting {
	align-self: end;
}

/* getProgressBar's container is a <span> (default inline → width/height ignored, so it
   collapsed to 0 height). Blockify it here — nested in __supporting it isn't a grid item
   that would auto-blockify, unlike taskProgressSummary where the bar is a direct grid cell. */
.projectProgressSummary__progressBar {
	display: block;
	width: 100%;
}

/* Bar fill matches the tier color. */
.projectProgressSummary__progressBar-inProgress .progressBar { background: var(--brand-primary); }
.projectProgressSummary__progressBar-complete .progressBar { background: var(--status-success); }

/**
* projectTimeSummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-April-08 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

/* Shared detail-card stack: icon+label header (bottom border) / large value / supporting (Budgeted | Logged) row. */
.projectTimeSummary__view {
	display: grid;
	row-gap: var(--gap-stack);
	grid-template-rows: auto auto 1fr;
	padding: var(--pad-card);
}

/* Permission self-hide: removed from the flex row so siblings stretch to fill. */
.projectTimeSummary__view-hidden {
	display: none;
}

.projectTimeSummary__iconLabelContainer {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

/* Duration figures — tabular so the value holds its width as it re-paints. */
.projectTimeSummary__timeLeftValue {
	color: var(--status-success);
	font-variant-numeric: tabular-nums;
}

/* Consumed time has exceeded the limit — surface the negative remainder in danger red. */
.projectTimeSummary__timeLeftValue-overBudget {
	color: var(--status-danger);
}

.projectTimeSummary__supporting {
	display: flex;
	justify-content: space-between;
	gap: var(--gap-inline);
}

.projectTimeSummary__consumed {
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/**
* projectFinancialSummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-April-08 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

/* Shared detail-card stack: icon+label header (bottom border) / large value / supporting (Rate | Remaining) row. */
.projectFinancialSummary__view {
	display: grid;
	row-gap: var(--gap-stack);
	grid-template-rows: auto auto 1fr;
	padding: var(--pad-card);
}

.projectFinancialSummary__view-hidden {
	display: none;
}

.projectFinancialSummary__iconLabelContainer {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

/* Money figures — tabular so the amounts line up column-wise and don't
   re-flow when the value changes. */
.projectFinancialSummary__billed {
	color: var(--status-success);
	font-variant-numeric: tabular-nums;
}

.projectFinancialSummary__supporting {
	display: flex;
	justify-content: space-between;
	gap: var(--gap-inline);
}

.projectFinancialSummary__remaining {
	text-align: right;
	font-variant-numeric: tabular-nums;
}

.projectFinancialSummary__remaining-overBudget {
	color: var(--status-danger);
}

/**
* projectTasks.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-May-31 Initial Version
* @version 2026-July-29 Spacing/type literals migrated onto the token contract's §Dense rungs — row chrome holds or tightens
*/

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

.projectTasks__view {
	display: grid;
	grid-template-rows: auto 1fr;
	gap: var(--gap-dense);
}

.projectTasks__heading {
	text-align: left;
}

.projectTasks__item {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
	padding: var(--pad-cell) 0;
}

/* Status dot — done is green, to-do is muted; matches the deadline/progress color language. */
.projectTasks__dot {
	width: .8rem;
	height: .8rem;
	border-radius: var(--radius-avatar);
	flex: none;
}

.projectTasks__dot-done {
	background: var(--status-success);
}

.projectTasks__dot-todo {
	background: var(--text-secondary);
}

.projectTasks__item-done {
	text-decoration: line-through;
	opacity: .6;
}

/**
* projectTaskTiles.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-29 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.projectTaskTiles__view {
	display: grid;
	grid-template-rows: 1fr;
	min-height: 0;
	height: 100%;
}

/* Bounded, scrolling list of the project's TaskTiles. `min-height:0` lets the
   1fr grid row actually shrink so `overflow:auto` engages instead of the list
   forcing the tab to grow unbounded. */
.projectTaskTiles__scrollArea {
	min-height: 0;
	display: flex;
	flex-direction: column;
	gap: var(--gap-dense);
}

/* Each tile is the scroll area's flex item (its `[data-slot]` host is `display:contents`).
   Pin the shared `.taskTile__view`'s margin here so no `auto` side margin can reach it:
   `auto` sides absorb the free space and suppress the column's `align-items:stretch`,
   leaving tiles centered at content width (unequal, staggered). The block margin does the
   vertical spacing. */
.projectTaskTiles__scrollArea .taskTile__view {
	margin: var(--gap-dense) 0;
	width: 100%;
}

.projectTaskTiles__empty {
	color: var(--text-secondary);
	font-style: italic;
}
/**
* projectTeamMembers.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-May-31 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.projectTeamMembers__view {
	display: grid;
	grid-template-rows: auto 1fr;
	gap: var(--gap-inline);
}

.projectTeamMembers__heading {
	text-align: left;
}

/* Bounded, scrolling list of TeamMemberTiles. `min-height:0` lets the 1fr grid
   row shrink so `overflow:auto` engages instead of the list forcing growth. */
.projectTeamMembers__scrollArea {
	min-height: 0;
	display: flex;
	flex-direction: column;
	gap: var(--gap-dense);
}

/**
* projectActiveTasks.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-29 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

.projectActiveTasks__view {
	display: grid;
	row-gap: var(--gap-stack);
	/* header · value · supporting · scrolling tile list (the list takes the slack). */
	grid-template-rows: auto auto auto 1fr;
	min-height: 0;
	padding: var(--pad-card);
}

.projectActiveTasks__iconLabelContainer {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.projectActiveTasks__value {
	font-size: var(--font-size-subheading);
	color: var(--brand-primary);
}

.projectActiveTasks__supporting {
	color: var(--text-secondary);
}

.projectActiveTasks__empty {
	color: var(--text-secondary);
	font-style: italic;
}

/* Bounded, scrolling list of the running TaskTiles. `min-height:0` lets the
   1fr grid row actually shrink so `overflow:auto` engages instead of the list
   forcing the card to grow unbounded. */
.projectActiveTasks__scrollArea {
	min-height: 0;
	max-height: 34rem;
	display: flex;
	flex-direction: column;
	gap: var(--gap-dense);
}

/* Stretch each tile to the same full width — a centering `margin` on the shared
   `.taskTile__view` would otherwise center it at content width (its `[data-slot]`
   host is `display:contents`, so the tile is the column flex item and the `auto` side
   margins suppress `align-items:stretch`). See projectTaskTiles.css for the full note. */
.projectActiveTasks__scrollArea .taskTile__view {
	margin: 0;
	width: 100%;
}

/**
* projectWorkingNow.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-29 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

.projectWorkingNow__view {
	display: grid;
	row-gap: var(--gap-stack);
	/* header · value · scrolling member-tile list (the list takes the slack). */
	grid-template-rows: auto auto 1fr;
	min-height: 0;
	padding: var(--pad-card);
}

.projectWorkingNow__iconLabelContainer {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.projectWorkingNow__value {
	font-size: var(--font-size-subheading);
	color: var(--brand-primary);
}

.projectWorkingNow__empty {
	color: var(--text-secondary);
	font-style: italic;
}

/* Bounded, scrolling list of the working TeamMemberTiles. `min-height:0` lets the
   1fr grid row shrink so `overflow:auto` engages instead of growing the card. */
.projectWorkingNow__scrollArea {
	min-height: 0;
	max-height: 34rem;
	display: flex;
	flex-direction: column;
	gap: var(--gap-dense);
}

/**
* projectBurndown.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-May-31 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.projectBurndown__view {
	display: grid;
	gap: var(--gap-stack);
	grid-template-rows: auto 1fr;
	min-height: 0;
	height: 100%;
	width: 100%;
}

.projectBurndown__title {
	margin: 0;
}

/* The graph fills the remaining track; LineGraph sizes its canvas from this. */
.projectBurndown__view .graph__view {
	min-height: 16rem;
	height: 100%;
}

.projectBurndown__loading,
.projectBurndown__empty {
	margin: auto;
	text-align: center;
	opacity: 0.7;
}

/**
 * projectGantt.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2026-May-31 Initial Version — project Gantt diagram (DOM bars + subtask grouping)
 * @version 2026-July-29 Spacing/type literals migrated onto the token contract's §Dense rungs — row chrome holds or tightens
 * @version 2026-August-14 Phone-band axis/row labels one rung up, with --line-height-tight so the fixed 1.5rem grid row still fits
 */

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

.projectGantt__view {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	width: 100%;
}

.projectGantt__title {
	margin: 0;
}

/* Centered like `.projectBurndown__empty` so the two diagrams' empty/loading
   states read the same (#883 review). */
.projectGantt__loading,
.projectGantt__empty {
	margin: auto;
	text-align: center;
	color: var(--text-primary);
	opacity: 0.7;
}

.projectGantt__track {
	display: flex;
	flex-direction: column;
	gap: var(--gap-tight);
	width: 100%;
}

.projectGantt__axis {
	display: flex;
	justify-content: space-between;
	font-size: var(--font-size-label);
	color: var(--text-primary);
	opacity: 0.7;
}

.projectGantt__axisLabel {
	margin: 0;
}

/* The rows grid is the positioning context for the absolute arrow overlay. The
   label column is a FIXED width so the overlay can offset past it (`left:
   var(--Gantt_Label_Width)`) and align its 0–100 x-axis with the lane column. */
.projectGantt__rows {
	position: relative;
	display: grid;
	grid-template-columns: var(--Gantt_Label_Width, 9rem) 1fr;
	grid-auto-rows: 1.5rem;
	align-items: center;
	column-gap: var(--gap-dense);
	row-gap: 0.1rem; /* intentional literal: 1px lane separation on a 1.5rem-row grid; any rung multiplies chart height by row count */
}

.projectGantt__label {
	margin: 0;
	font-size: var(--font-size-label);
	color: var(--text-primary);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* The bar's positioning track: a full-width lane the absolute bar sits within. */
.projectGantt__lane {
	position: relative;
	height: 1.25rem;
	background: var(--surface-card);
	border-radius: var(--radius-dense);
}

/* `left` / `width` are set inline as a % of the [xMin, xMax] domain by the component. */
.projectGantt__bar {
	position: absolute;
	top: 0;
	height: 100%;
	min-width: 2px;
	border-radius: var(--radius-dense);
	background: var(--brand-accent);
}

/* Interval-activity fallback span (task had no planned start/deadline). */
.projectGantt__bar--fallback {
	background: repeating-linear-gradient(
		45deg,
		var(--brand-accent),
		var(--brand-accent) 4px,
		transparent 4px,
		transparent 8px
	);
	opacity: 0.75;
}

/* Dependency arrows: one SVG stretched over the lane column (offset past the
   fixed label column). Aspect-free so the model's 0–100 x / row-unit y map
   straight onto the box; non-scaling stroke keeps the line crisp under stretch. */
.projectGantt__arrows {
	position: absolute;
	left: var(--Gantt_Label_Width, 9rem);
	right: 0;
	top: 0;
	bottom: 0;
	height: 100%;
	pointer-events: none;
	overflow: visible;
}

.projectGantt__arrow {
	fill: none;
	stroke: var(--brand-accent);
	stroke-width: 1;
	opacity: 0.6;
	vector-effect: non-scaling-stroke;
}

.projectGantt__arrowHead {
	fill: var(--brand-accent);
}

/* Phone band: --font-size-label measures 8.29px at 390px (8.00px at 320px) on a
   dense chart. One rung up, paired with --line-height-tight so the taller text
   still fits the fixed 1.5rem grid row — measured 39.0px for a 3-row block
   before and after. */
:root[data-viewport="phone"] .projectGantt__axis,
:root[data-viewport="phone"] .projectGantt__label {
	font-size: var(--font-size-caption);
	line-height: var(--line-height-tight);
}

/**
* taskBurndown.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskBurndown__view {
	display: grid;
	gap: var(--gap-stack);
	grid-template-rows: auto 1fr;
	min-height: 0;
	height: 100%;
	width: 100%;
}

.taskBurndown__title {
	margin: 0;
}

/* The graph fills the remaining track; LineGraph sizes its canvas from this. */
.taskBurndown__view .graph__view {
	min-height: 16rem;
	height: 100%;
}

.taskBurndown__loading,
.taskBurndown__empty {
	margin: auto;
	text-align: center;
	opacity: 0.7;
}

/**
 * taskGantt.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2026-June-10 Initial Version — task Gantt diagram (DOM bars + subtask grouping)
 * @version 2026-July-29 Spacing/type literals migrated onto the token contract's §Dense rungs — row chrome holds or tightens
 * @version 2026-August-14 Phone-band axis/row labels one rung up, with --line-height-tight so the fixed 1.5rem grid row still fits
 */

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

.taskGantt__view {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	width: 100%;
}

.taskGantt__title {
	margin: 0;
}

/* Centered like `.taskBurndown__empty` so the two diagrams' empty/loading
   states read the same. */
.taskGantt__loading,
.taskGantt__empty {
	margin: auto;
	text-align: center;
	color: var(--text-primary);
	opacity: 0.7;
}

.taskGantt__track {
	display: flex;
	flex-direction: column;
	gap: var(--gap-tight);
	width: 100%;
}

.taskGantt__axis {
	display: flex;
	justify-content: space-between;
	font-size: var(--font-size-label);
	color: var(--text-primary);
	opacity: 0.7;
}

.taskGantt__axisLabel {
	margin: 0;
}

/* The rows grid is the positioning context for the absolute arrow overlay. The
   label column is a FIXED width so the overlay can offset past it (`left:
   var(--Gantt_Label_Width)`) and align its 0–100 x-axis with the lane column. */
.taskGantt__rows {
	position: relative;
	display: grid;
	grid-template-columns: var(--Gantt_Label_Width, 9rem) 1fr;
	grid-auto-rows: 1.5rem;
	align-items: center;
	column-gap: var(--gap-dense);
	row-gap: 0.1rem; /* intentional literal: 1px lane separation on a 1.5rem-row grid; any rung multiplies chart height by row count */
}

.taskGantt__label {
	margin: 0;
	font-size: var(--font-size-label);
	color: var(--text-primary);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* The bar's positioning track: a full-width lane the absolute bar sits within. */
.taskGantt__lane {
	position: relative;
	height: 1.25rem;
	background: var(--surface-card);
	border-radius: var(--radius-dense);
}

/* `left` / `width` are set inline as a % of the [xMin, xMax] domain by the component. */
.taskGantt__bar {
	position: absolute;
	top: 0;
	height: 100%;
	min-width: 2px;
	border-radius: var(--radius-dense);
	background: var(--brand-accent);
}

/* Interval-activity fallback span (task had no planned start/deadline). */
.taskGantt__bar--fallback {
	background: repeating-linear-gradient(
		45deg,
		var(--brand-accent),
		var(--brand-accent) 4px,
		transparent 4px,
		transparent 8px
	);
	opacity: 0.75;
}

/* Dependency arrows: one SVG stretched over the lane column (offset past the
   fixed label column). Aspect-free so the model's 0–100 x / row-unit y map
   straight onto the box; non-scaling stroke keeps the line crisp under stretch. */
.taskGantt__arrows {
	position: absolute;
	left: var(--Gantt_Label_Width, 9rem);
	right: 0;
	top: 0;
	bottom: 0;
	height: 100%;
	pointer-events: none;
	overflow: visible;
}

.taskGantt__arrow {
	fill: none;
	stroke: var(--brand-accent);
	stroke-width: 1;
	opacity: 0.6;
	vector-effect: non-scaling-stroke;
}

.taskGantt__arrowHead {
	fill: var(--brand-accent);
}

/* Phone band: --font-size-label measures 8.29px at 390px (8.00px at 320px) on a
   dense chart. One rung up, paired with --line-height-tight so the taller text
   still fits the fixed 1.5rem grid row — measured 39.0px for a 3-row block
   before and after. */
:root[data-viewport="phone"] .taskGantt__axis,
:root[data-viewport="phone"] .taskGantt__label {
	font-size: var(--font-size-caption);
	line-height: var(--line-height-tight);
}

/**
 * intervalTile.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2020-04-07 Initial Version
 * @version 2026-July-03 Bulk-selection checkbox (#896); the modal-only
 *          .intervalTile__editPanel rule pruned with the dialog flow it styled
 *          (the editor now expands in place inside the tile)
 * @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the edit/delete buttons always (#1641)
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 */

.intervalTile__view {
	position: relative;
	width: 100%;
	padding: var(--pad-row);
	border-radius: var(--radius-card);
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
}

/* Line 1: member (left) + total (right). */
.intervalTile__mainRow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-stack);
}

.intervalTile__memberGroup {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
	min-width: 0;
}

.intervalTile__total {
	font-weight: 600;
	white-space: nowrap;
}

/* Line 2: the muted date/time range, indented under the member name. */
.intervalTile__range {
	opacity: 0.7;
	padding-left: 2.5rem; /* intentional literal: avatar-aligned indent matched to the member row above, not a density step */
}

.intervalTile__teamMember {}

.intervalTile__editButton {
	cursor: pointer;
	position: absolute;
	top: 0;
	right: 0;
	transform: translate(50%, -50%);
}

.intervalTile__deleteButton {
	cursor: pointer;
	position: absolute;
	top: 0;
	right: 0;
	transform: translate(-50%, -50%);
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the edit/delete buttons behind it — touch devices see them always. */
@media (hover: hover) {

	.intervalTile__editButton,
	.intervalTile__deleteButton {
		opacity: 0;
	}

	.intervalTile__view:hover .intervalTile__editButton {
		opacity: 1;
	}

	.intervalTile__view:hover .intervalTile__deleteButton {
		opacity: 1;
	}
}

/**
* taskHeader.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version — extracted from taskPanel.css; mirrors projectHeader.css
* @version 2026-June-30 Meta row under the title (status dot + Created + Owner)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskHeader__view {
	display: grid;
	gap: var(--gap-tile);
	align-items: center;
	grid-template-columns: minmax(0, 1fr) auto;
}

.taskHeader__taskName {
	text-align: left;
}

.taskHeader__actionButtonsContainer {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: var(--gap-tile);
}

.taskHeader__status {
	border: var(--border-shorthand);
	border-radius: var(--radius-card);
	padding: 0 var(--pad-dense);
	background-color: var(--brand-accent);
}

:root[data-viewport="phone"] .taskHeader__view {
	padding-left: var(--pad-shell);
}

/**
* taskDeadlineSummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-June-30 Permission self-hide (display:none) so flex siblings stretch
* @version 2026-June-30 Mockup parity: deadline date + overdue countdown (dropped the start-date row)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

.taskDeadlineSummary__view {
	display: grid;
	row-gap: var(--gap-stack);
	grid-template-rows: auto auto auto;
	padding: var(--pad-card);
}

/* Permission self-hide: removed from the flex row so siblings stretch to fill. */
.taskDeadlineSummary__view-hidden {
	display: none;
}

.taskDeadlineSummary__iconLabelContainer {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.taskDeadlineSummary__label {
	text-align: left;
}

.taskDeadlineSummary__deadlineValue {
	color: var(--status-success);
}

.taskDeadlineSummary__countdown {
	opacity: .7;
}

.taskDeadlineSummary__countdown-overdue {
	color: var(--status-danger);
	opacity: 1;
}

/**
* taskProgressSummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-June-30 "<done> of <total> completed" sub-text row (mockup parity)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

.taskProgressSummary__view {
	display: grid;
	row-gap: var(--gap-stack);
	grid-template-rows: auto 1fr auto;
	grid-template-areas:
		'taskProgressSummary_iconLabel taskProgressSummary_percentageValue'
		'taskProgressSummary_progressBar taskProgressSummary_progressBar'
		'taskProgressSummary_completed taskProgressSummary_completed';
	padding: var(--pad-card);
}

.taskProgressSummary__iconLabelContainer {
	grid-area: taskProgressSummary_iconLabel;
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.taskProgressSummary__percentageValue {
	grid-area: taskProgressSummary_percentageValue;
	text-align: right;
	color: var(--status-success);
}

.taskProgressSummary__progressBar {
	grid-area: taskProgressSummary_progressBar;
}

.taskProgressSummary__completedValue {
	grid-area: taskProgressSummary_completed;
	opacity: .7;
	text-align: right;
}

/**
* taskTimeSummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-June-30 Permission self-hide (display:none) so flex siblings stretch
* @version 2026-June-30 Dropped the Accuracy sub-metric style (moved to TaskAccuracySummary)
* @version 2026-June-30 Mockup parity: total tracked time + "Total time" (dropped the time-left/estimate split)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

.taskTimeSummary__view {
	display: grid;
	row-gap: var(--gap-stack);
	grid-template-rows: auto auto auto;
	padding: var(--pad-card);
}

/* Permission self-hide: removed from the flex row so siblings stretch to fill. */
.taskTimeSummary__view-hidden {
	display: none;
}

.taskTimeSummary__iconLabelContainer {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.taskTimeSummary__label {
	text-align: left;
}

/* The remaining-value color is set inline by getStopColor (gradient success → danger). */

/* The countdown re-paints every second (TaskTimeSummary.js `#paintValue`), so
   proportional figures visibly jitter — tabular figures hold the width. */
.taskTimeSummary__remainingValue {
	font-variant-numeric: tabular-nums;
}

.taskTimeSummary__total {
	opacity: .6;
	font-variant-numeric: tabular-nums;
}

/**
* taskFinancialSummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

.taskFinancialSummary__view {
	display: grid;
	row-gap: var(--gap-stack);
	grid-template-rows: auto 1fr;
	grid-template-columns: 1fr 1fr;
	padding: var(--pad-card);
}

.taskFinancialSummary__view-hidden {
	display: none;
}

.taskFinancialSummary__iconLabelContainer {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.taskFinancialSummary__label {
	text-align: left;
}

/* Money figures — tabular so the amounts line up column-wise and don't
   re-flow when the value changes. */
.taskFinancialSummary__billed {
	text-align: right;
	color: var(--status-success);
	font-variant-numeric: tabular-nums;
}

.taskFinancialSummary__total {
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/**
* taskSubtasks.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-July-02 Loading-arm skeleton list stack
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskSubtasks__view {
	display: grid;
	grid-template-rows: auto auto minmax(0, 3fr) minmax(0, 1fr);
	gap: var(--gap-inline);
}

/* The subtask list is the flexible middle region (parent above, dependencies below);
   it scrolls inside its `.scrollArea` wrapper, which owns the bounded 3fr-row height. */
.taskSubtasks__list {
	min-height: 0;
}

.taskSubtasks__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
}

/* Loading-arm stand-in for the subtask list. */
.taskSubtasks__skeletonList {
	display: flex;
	flex-direction: column;
	gap: var(--gap-dense);
}

.taskSubtasks__item {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.taskSubtasks__itemName {
	cursor: pointer;
	flex: 1;
}

.taskSubtasks__itemStatus {
	opacity: .7;
}

.taskSubtasks__item-done {
	text-decoration: line-through;
	opacity: .6;
}

/* Parent sits first, above the subtask list — a bottom divider separates it. */
.taskSubtasks__parent {
	display: flex;
	align-items: baseline;
	gap: var(--gap-inline);
	padding-bottom: var(--pad-dense);
	border-bottom: var(--border-shorthand);
}

.taskSubtasks__parentName {
	cursor: pointer;
}

/* Blocked-by | Blocks — a fixed two-column fr grid at the bottom, with a top divider.
   Columns stretch to the row height (no `align-items: start`) so each list can scroll. */
.taskSubtasks__dependencies {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--gap-inline);
	min-height: 0;
	padding-top: var(--pad-dense);
	border-top: var(--border-shorthand);
}

/* Heading pinned on top, scrolling list below: the `minmax(0, 1fr)` row lets its
   `.scrollArea` wrapper shrink so `overflow` engages instead of forcing growth. */
.taskSubtasks__dependencyColumn {
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
	gap: var(--gap-tight);
	min-height: 0;
}

.taskSubtasks__relationHeading {
	text-align: left;
}

.taskSubtasks__blocker>* {
	cursor: pointer;
}

/**
* taskStatusTimeline.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskStatusTimeline__view {
	display: grid;
	grid-template-rows: auto 1fr;
	gap: var(--gap-inline);
	padding: var(--pad-card);
}

/* Uniform card header — left-aligned, no separator line under it (matches taskDescription). */
.taskStatusTimeline__heading {
	text-align: left;
}

.taskStatusTimeline__entry {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
}

.taskStatusTimeline__entryMeta {
	opacity: .7;
}

/**
* taskMemberLoad.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
* @version 2026-July-29 Spacing/type literals migrated onto the token contract's §Dense rungs — row chrome holds or tightens
*/

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token contract's §Dense exception */

.taskMemberLoad__view {
	display: grid;
	grid-template-rows: auto 1fr;
	gap: var(--gap-dense);
}

.taskMemberLoad__item {
	padding: var(--pad-cell) 0;
}

/**
* taskTeamMembers.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-30 Initial Version
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskTeamMembers__view {
	display: grid;
	grid-template-rows: auto 1fr;
	gap: var(--gap-inline);
}

.taskTeamMembers__heading {
	text-align: left;
}

/* Bounded, scrolling list of TeamMemberTiles. `min-height:0` lets the 1fr grid
   row shrink so `overflow:auto` engages instead of the list forcing growth. */
.taskTeamMembers__scrollArea {
	min-height: 0;
	display: flex;
	flex-direction: column;
	gap: var(--gap-dense);
}

/**
* taskAccuracySummary.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-30 Initial Version — 5th stat card (tracked-vs-estimate accuracy %)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder; card rhythm unified on --gap-stack
*/

.taskAccuracySummary__view {
	display: grid;
	row-gap: var(--gap-stack);
	grid-template-rows: auto 1fr;
}

/* Permission self-hide: removed from the flex row so siblings stretch to fill. */
.taskAccuracySummary__view-hidden {
	display: none;
}

.taskAccuracySummary__label {
	border-bottom: var(--border-shorthand);
	padding-bottom: var(--pad-dense);
}

.taskAccuracySummary__accuracyValue {
	border-bottom: var(--border-shorthand);
	padding-bottom: var(--pad-dense);
	color: var(--status-success);
	text-align: right;
}

.taskAccuracySummary__subLabel {
	opacity: .7;
	text-align: right;
}

/**
* taskDescription.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-30 Initial Version — Details left-column description card
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskDescription__view {
	display: grid;
	grid-template-rows: auto 1fr;
	gap: var(--gap-inline);
	padding: var(--pad-card);
}

.taskDescription__heading {
	text-align: left;
}

.taskDescription__text {
	color: var(--text-secondary);
}

/**
* taskActivity.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-30 Initial Version — full task audit feed (Activity tab)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/

.taskActivity__view {
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
	gap: var(--gap-inline);
}

.taskActivity__heading {
	border-bottom: var(--border-shorthand);
	padding-bottom: var(--pad-dense);
}

.taskActivity__list {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
}

.taskActivity__entry {
	display: flex;
	align-items: flex-start;
	gap: var(--gap-inline);
}

.taskActivity__body {
	display: flex;
	flex-direction: column;
	gap: .15rem; /* intentional literal: 1.5px optical split between an entry line and its meta; the 4px --gap-tight rung would grow every feed row */
	flex: 1 1 auto;
}

.taskActivity__meta {
	display: flex;
	gap: var(--gap-inline);
	opacity: .7;
}

.taskActivity__empty {
	opacity: .7;
}

/**
* taskTime.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-24 Initial Version — TaskPanel "Time" section: by-member interval list + bulk add
* @version 2026-July-03 Bulk action bar over the right pane (#896)
* @version 2026-July-29 Spacing and type literals migrated onto the role-token ladder (roomy posture)
*/
.taskTime__view {
	width: 100%;
	height: 100%;
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
	gap: var(--gap-tile);
	min-height: 0;
}

.taskTime__filterBar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--gap-tile);
}

.taskTime__dateFilter,
.taskTime__timeFilter {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--gap-inline);
}

.taskTime__dateRange {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--gap-inline);
}

.taskTime__logButton {
	margin-left: auto;
}

.taskTime__intervalScrollArea {
	flex: 1;
	min-height: 0;
	padding: var(--pad-card);
	align-items: center;
}

.taskTime__emptyFilters {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--gap-inline);
}

.taskTime__bulkAdd {
	width: 100%;
	height: 100%;
	padding: var(--pad-card);
}

.overlayPanel:has(.taskTime__bulkAdd) {
	width: 35%;
	min-width: 20rem;
	background: var(--surface-raised);
	top: 0;
	left: 0;
	height: 100%;
}

:root[data-viewport="phone"] .overlayPanel:has(.taskTime__bulkAdd) {
	width: 100%;
}

.overlayPanel:has(.taskTime__bulkAdd) .overlayPanel__closeButton {
	display: none;
}

/**
* entityInformationPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-31 Initial Version
* @version 2026-August-03 Status row (label + gated status slider)
* @version 2026-August-03 Stack the status row above the EntityInfo container
*/

.entityInformationPanel__view {
	display: grid;
	gap: var(--gap-stack);
	align-content: start;
}

:root[data-viewport="phone"] .entityInformationPanel__view {
	padding: var(--pad-sheet);
}

.entityInformationPanel__statusSlider {
	justify-self: end;
}

/**
* entityInfo.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-03 Initial Version
*/

.entityInfo__view {
	display: grid;
	gap: var(--gap-stack);
	padding: var(--pad-card);
}

.entityInfo__headerRow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
}

.entityInfo__heading,
.entityInfo__fieldHeading,
.entityInfo__contactHeading {
	text-align: left;
}

.entityInfo__fieldContainer {
	display: grid;
	gap: var(--gap-tight);
	padding-top: var(--pad-row);
}

.entityInfo__contactsContainer {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
	gap: var(--gap-section);
	padding-top: var(--pad-row);
}

.entityInfo__contactGroup {
	display: grid;
	gap: var(--gap-dense);
	height: fit-content;
}

/**
* entityDangerZone.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-03 Initial Version
*/

.entityDangerZone__view {
	display: grid;
	gap: var(--gap-stack);
	padding: var(--pad-card);
	border: 1px solid var(--status-danger);
}

.entityDangerZone__view:empty {
	display: none;
}

.entityDangerZone__header {
	display: grid;
	gap: var(--gap-tight);
}

.entityDangerZone__heading {
	color: var(--status-danger);
}

.entityDangerZone__heading,
.entityDangerZone__warning,
.entityDangerZone__actionTitle,
.entityDangerZone__actionDescription {
	text-align: left;
}

.entityDangerZone__action {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
	padding-top: var(--pad-row);
	border-top: 1px solid var(--status-danger);
}

.entityDangerZone__actionText {
	display: grid;
	gap: var(--gap-tight);
}

.entityDangerZone__actionButton {
	flex-shrink: 0;
	color: var(--status-danger);
	border-color: var(--status-danger);
}

/**
* deleteEntityView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-03 Initial Version
*/

.deleteEntityView__view {
	display: grid;
	gap: var(--gap-stack);
	padding: var(--pad-sheet);
}

.deleteEntityView__heading,
.deleteEntityView__warning,
.deleteEntityView__instruction {
	text-align: left;
}

.deleteEntityView__warning {
	color: var(--status-danger);
}

.deleteEntityView__buttonArea {
	display: flex;
	gap: var(--gap-tile);
	justify-content: end;
	padding-top: var(--pad-row);
}

/**
* entitySettingsTile.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-31 Initial Version
* @version 2026-August-04 The tile is a real button now (getButton's `tile` variant) for keyboard operability, so the button default of centring its content needs undoing for an icon-then-label row; the row gap is declared here rather than on base `.tile`, which would have re-spaced every tile in the app (#1771 review 4)
*/

.entitySettingsTile__view {
	justify-content: flex-start;
	gap: var(--gap-inline);
}

.entitySettingsTile__view-selected {
	border-color: var(--brand-accent);
}

/**
* cardBrandMark.css
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-10 Initial Version
*/

.cardBrandMark__view {
	display: flex;
	align-items: center;
}

.cardBrandMark__label {
	color: var(--text-secondary);
	font-weight: var(--font-weight-medium);
	white-space: nowrap;
}

.cardBrandMark__plate {
	display: flex;
	align-items: center;
	justify-content: center;
	/* intentional literal: card-network minimum mark size, px-anchored */
	width: 64px;
	height: 44px;
	flex: 0 0 auto;
	background: var(--surface-brandmark);
	border: 1px solid var(--border-default);
	border-radius: var(--radius-dense);
}

.cardBrandMark__image {
	/* intentional literal: Amex Blue Box 40px height floor plus its clear space */
	max-width: 56px;
	max-height: 40px;
	object-fit: contain;
}

.cardBrandMark__glyph {
	color: var(--text-secondary);
}

/**
* storageMeter.css
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-10 Initial Version
*/

.storageMeter__view {
	display: grid;
	gap: var(--gap-tight);
}

.storageMeter__labelRow {
	display: flex;
	justify-content: space-between;
	gap: var(--gap-inline);
	color: var(--text-secondary);
}

.storageMeter__figures {
	font-variant-numeric: tabular-nums;
}

.storageMeter__bar {
	border-radius: var(--radius-pill);
}

.storageMeter__bar-ok .progressBar {
	background: var(--chart-active);
}

.storageMeter__bar-nearing .progressBar {
	background: var(--status-warning);
}

.storageMeter__bar-full .progressBar,
.storageMeter__bar-grace .progressBar,
.storageMeter__bar-readOnly .progressBar {
	background: var(--status-danger);
}

/**
* planStatusCard.css
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-10 Initial Version
* @version 2026-August-12 The scheduled-change note and the intro-offer note (#1888)
*/

.planStatusCard__view {
	display: grid;
	gap: var(--gap-stack);
}

.planStatusCard__headerRow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
}

.planStatusCard__planName {
	font-size: var(--font-size-heading);
	font-weight: var(--font-weight-heading);
	font-family: var(--font-display);
}

.planStatusCard__priceRow {
	display: flex;
	align-items: baseline;
	gap: var(--gap-inline);
	color: var(--text-secondary);
}

.planStatusCard__price,
.planStatusCard__renewal {
	font-family: var(--font-body);
	font-variant-numeric: tabular-nums;
}

.planStatusCard__pendingChange,
.planStatusCard__introOffer {
	color: var(--text-secondary);
	font-family: var(--font-body);
	font-variant-numeric: tabular-nums;
}

.planStatusCard__intervalRow {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.planStatusCard__annualNote {
	color: var(--status-success);
	font-weight: var(--font-weight-medium);
}

.planStatusCard__planSlider {
	width: 100%;
}

.planStatusCard__statusText {
	color: var(--text-secondary);
	line-height: var(--line-height-relaxed);
}

.planStatusCard__autoRenewRow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
	border-top: 1px solid var(--border-default);
	padding-top: var(--pad-row);
}

.planStatusCard__autoRenewLabel {
	font-weight: var(--font-weight-medium);
}

.planStatusCard__autoRenewControl {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.planStatusCard__autoRenewValue {
	color: var(--text-secondary);
}

.planStatusCard__dunningBanner {
	display: grid;
	gap: var(--gap-inline);
	background: color-mix(in srgb, var(--status-danger) 12%, transparent);
	border: 1px solid var(--status-danger);
	border-radius: var(--radius-card);
	padding: var(--pad-card);
}

.planStatusCard__dunningActions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--gap-inline);
}

.planStatusCard__storageMeter {
	border-top: 1px solid var(--border-default);
	padding-top: var(--pad-row);
}

.planStatusCard__unavailable {
	padding: var(--pad-card);
}

:root[data-viewport="phone"] .planStatusCard__toggle {
	min-height: var(--touch-target-primary);
}

/**
* paymentMethodList.css
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-10 Initial Version
* @version 2026-August-12 The payout section's advisory prompt (#1881)
*/

.paymentMethodList__view {
	display: grid;
	gap: var(--gap-stack);
}

.paymentMethodList__heading {
	font-size: var(--font-size-subheading);
	font-weight: var(--font-weight-heading);
}

.paymentMethodList__explainer,
.paymentMethodList__emptyState,
.paymentMethodList__unavailable {
	color: var(--text-secondary);
	line-height: var(--line-height-relaxed);
}

.paymentMethodList__payoutPrompt {
	color: var(--text-secondary);
	line-height: var(--line-height-relaxed);
	padding: var(--pad-row) var(--pad-card);
	border-radius: var(--radius-dense);
	background: var(--surface-card);
}

.paymentMethodList__rows {
	display: grid;
	gap: var(--gap-dense);
}

.paymentMethodList__addAction {
	justify-self: start;
	color: var(--text-link);
	padding: var(--pad-dense) 0;
}

.paymentMethodRow__view {
	display: grid;
	grid-template-columns: auto 1fr auto auto;
	align-items: center;
	gap: var(--gap-inline);
	padding: var(--pad-row) var(--pad-card);
	border-radius: var(--radius-dense);
	background: var(--surface-card);
	box-shadow: var(--elevation-flat);
	line-height: var(--line-height-tight);
}

.paymentMethodList__view-payoutAccount .paymentMethodRow__view {
	grid-template-columns: 1fr auto auto;
}

.paymentMethodRow__view:hover {
	background: var(--surface-hover);
}

.paymentMethodRow__text {
	display: grid;
	gap: var(--gap-hairline);
	min-width: 0;
}

.paymentMethodRow__title,
.paymentMethodRow__meta {
	font-variant-numeric: tabular-nums;
}

.paymentMethodRow__meta {
	color: var(--text-secondary);
}

.paymentMethodRow__badges {
	display: flex;
	align-items: center;
	gap: var(--gap-tight);
}

.paymentMethodRow__actions {
	display: flex;
	align-items: center;
	gap: var(--gap-tight);
}

@media (hover: hover) {
	.paymentMethodRow__actions {
		opacity: 0;
	}

	.paymentMethodRow__view:hover .paymentMethodRow__actions,
	.paymentMethodRow__view:focus-within .paymentMethodRow__actions {
		opacity: 1;
	}
}

.paymentMethodRow__action {
	color: var(--text-link);
}

:root[data-viewport="phone"] .paymentMethodRow__view {
	grid-template-columns: auto 1fr auto;
}

:root[data-viewport="phone"] .paymentMethodRow__actions {
	min-height: var(--touch-target-primary);
	min-width: var(--touch-target-primary);
}

:root[data-viewport="phone"] .paymentMethodList__addAction {
	min-height: var(--touch-target-primary);
	min-width: var(--touch-target-primary);
}

/**
* subscribeConfirmView.css
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-10 Initial Version
*/

.subscribeConfirmView__view {
	display: grid;
	gap: var(--gap-stack);
	padding: var(--pad-sheet);
	border-radius: var(--radius-sheet);
	max-width: 44rem;
}

.subscribeConfirmView__heading {
	font-size: var(--font-size-subheading);
	font-weight: var(--font-weight-heading);
}

.subscribeConfirmView__cadence {
	color: var(--text-secondary);
	font-variant-numeric: tabular-nums;
}

.subscribeConfirmView__body {
	line-height: var(--line-height-relaxed);
	font-variant-numeric: tabular-nums;
}

.subscribeConfirmView__buttonArea {
	display: flex;
	justify-content: flex-end;
	gap: var(--gap-inline);
}

/**
* stripeElementsHost.css
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-21 Initial Version — mount reservations moved from addPaymentMethodView.css
*/

.stripeElementsHost__view {
	display: grid;
	gap: var(--gap-stack);
}

.stripeElementsHost__paymentMount {
	/* intentional literal: reserves the measured Elements iframe height */
	min-height: 22rem;
}

.stripeElementsHost__addressMount {
	/* intentional literal: reserves the measured Address Element height */
	min-height: 16rem;
}

/**
* addPaymentMethodView.css
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-10 Initial Version
* @version 2026-August-21 Stripe mount reservations moved to stripeElementsHost.css
*/

.addPaymentMethodView__view {
	display: grid;
	gap: var(--gap-stack);
	padding: var(--pad-sheet);
	border-radius: var(--radius-sheet);
	max-width: 48rem;
}

.addPaymentMethodView__heading {
	font-size: var(--font-size-subheading);
	font-weight: var(--font-weight-heading);
}

.addPaymentMethodView__notice {
	color: var(--text-secondary);
}

.addPaymentMethodView__error {
	color: var(--status-danger);
}

.addPaymentMethodView__processorLine {
	color: var(--text-secondary);
}

.addPaymentMethodView__buttonArea {
	display: flex;
	justify-content: flex-end;
	gap: var(--gap-inline);
}

/**
* addPayoutAccountView.css
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-10 Initial Version
* @version 2026-August-12 The required account-holder-name field (#1881)
*/

.addPayoutAccountView__view {
	display: grid;
	gap: var(--gap-stack);
	padding: var(--pad-sheet);
	border-radius: var(--radius-sheet);
	max-width: 44rem;
}

.addPayoutAccountView__heading {
	font-size: var(--font-size-subheading);
	font-weight: var(--font-weight-heading);
}

.addPayoutAccountView__notice,
.addPayoutAccountView__processorLine {
	color: var(--text-secondary);
}

.addPayoutAccountView__error {
	color: var(--status-danger);
}

.addPayoutAccountView__nameField {
	display: grid;
	gap: var(--gap-tight);
}

.addPayoutAccountView__nameLabel {
	color: var(--text-secondary);
}

.addPayoutAccountView__buttonArea {
	display: flex;
	justify-content: flex-end;
	gap: var(--gap-inline);
}

/**
* application.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2022-May-25 Initial Version
* @version 2026-July-29 Positional shell margins marked; no spacing rhythm here
* @version 2026-August-04 Shell view opts height/width out of the global transition: all — its dvh sizing re-resolves as the mobile toolbar moves (#1822)
* @version 2026-August-14 Phone-band rail gutter re-expressed through --gap-* roles — the desktop 5rem/5rem/.5rem spent 45.6px (11.7%) of a 390px viewport on nothing
* @version 2026-August-14 .application__skipLink — the first tab stop, parked off-screen until focused
*/

.application__view {
	height: 100dvh;
	width: 100dvw;
	display: grid;
	grid-template-areas:
		'application_header application_header application_header'
		'application_navigationRail application_mainPanel application_onlineIndicator';
	grid-template-rows: auto minmax(0, 1fr);
	grid-template-columns: auto minmax(0, 1fr) auto;
	position: relative;
	background: var(--surface-page);
	background-repeat: no-repeat;
	background-size: cover;
	min-height: 0;
	transition: all var(--transition-base), height 0s, width 0s;
}

.application__skipLink {
	position: absolute;
	top: var(--pad-dense);
	left: var(--pad-dense);
	z-index: 1000;
	padding: var(--pad-card);
	border-radius: var(--radius-button);
	background: var(--surface-raised);
	box-shadow: var(--elevation-overlay);
	transform: translateY(-300%);
}

.application__skipLink:focus,
.application__skipLink:focus-visible {
	transform: translateY(0);
}

.application__mainHeader {
	grid-area: application_header;
}

.application__navigationRail {
	grid-area: application_navigationRail;
	margin: 5rem 5rem auto .5rem; /* intentional literal: positional (`auto`) anchor margin, not spacing rhythm */
}

.application__mainPanel {
	grid-area: application_mainPanel;
}

.application__onlineIndicator {
	grid-area: application_onlineIndicator;
	letter-spacing: 5px;
	margin: 10rem 1rem auto; /* intentional literal: positional (`auto`) anchor margin, not spacing rhythm */
}

/* The desktop gutter measures 41.5px top, 41.5px right and 4.2px left at 390px —
   45.6px of a 390px viewport. Role tokens bring it to 19.9 / 3.3 / 3.3px; the
   `auto` bottom is the positional anchor and survives. */
:root[data-viewport="phone"] .application__navigationRail {
	margin: var(--gap-section) var(--gap-tight) auto var(--gap-tight);
}

/**
* viewManager.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2022-May-31 Initial Version
* @version 2026-July-29 Spacing literal collapsed onto the app.css role tokens
*/

.viewManager__view {
	height: 100%;
	/* padding: 2rem; */
}

.viewManager__mainPanel {
	width: 100%;
	height: 100%;
	overflow: hidden;
	padding-bottom: var(--gap-stack);
}

/**
* displayOverlay.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2022-October-24 Initial Version
* @version 2026-July-17 Phone rules re-gated :root[data-mobile] → :root[data-viewport="phone"] (decision 0004 phase 1, #1684)
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
* @version 2026-August-14 Both surfaces are native `<dialog>`s now: the UA chrome (border,
*   padding, margin:auto, fit-content sizing, :modal max-width/max-height + overflow, Canvas
*   background/color) is reset here — at ZERO specificity through `:where()`, so the reset
*   only ever beats the UA sheet and never an authored rule (`.dialog__view-translucentBlack`,
*   `.overlayPanel`'s own surface). `::backdrop` is transparent so the UA scrim never stacks
*   on top of the authored one.
*/

.displayOverlay__view {}

/* #region native <dialog> UA-chrome reset */

:where(.overlayPanel, .mainView__floatingPanel__background) {
	border: 0;
	padding: 0;
	margin: 0;
	max-width: none;
	max-height: none;
	overflow: visible;
	background: transparent;
	color: inherit;
}

:where(.overlayPanel, .mainView__floatingPanel__background)::backdrop {
	background: transparent;
}

/* #endregion */

.overlayPanel {
	height: 100%;
	width: 100%;
	position: absolute;
	background: var(--surface-page);
	z-index: 2;
	-webkit-backdrop-filter: var(--surface-blur);
	backdrop-filter: var(--surface-blur);
	/* Swipe-to-dismiss (#1641): let the browser keep vertical scrolling, but
	   hand horizontal pointer sequences to the panel's Pointer Events handlers
	   instead of cancelling them for a (nonexistent) horizontal scroll. */
	touch-action: pan-y;
	/* A 110vh slide is the largest surface in the app, so it gets the slow rung
	   and a decelerating curve rather than the global's symmetric one. `all` is
	   deliberate: this is a backdrop-filter surface whose background and shadow
	   must keep cross-fading when the theme changes — a named list would snap
	   them. NOTE: keep the total ≤550ms — DisplayDialog.js:137 and
	   DisplayOverlay.js:252 detach the node on a hardcoded timer. */
	transition: all var(--motion-slow) var(--ease-enter);
}

/* While a swipe drag is live the panel mirrors the pointer via an inline
   transform each move — any transition would lag it a frame behind the finger. */
.overlayPanel--dragging {
	transition: none;
	user-select: none;
}

.overlayPanel__closeButton {
	position: absolute;
	top: 2rem;
	left: 1rem;
	transform: rotate(180deg);
	fill: var(--brand-accent);
	z-index: 1;
}

:root[data-viewport="phone"] .icon__view:where(button):has(> .overlayPanel__closeButton) {
	position: absolute;
	top: 0.6rem;
	left: 0;
	z-index: 1;
	min-width: var(--touch-target-primary);
	min-height: var(--touch-target-primary);
	align-items: center;
	justify-content: center;
}

:root[data-viewport="phone"] .icon__view:where(button):has(> .overlayPanel__closeButton) .overlayPanel__closeButton {
	position: static;
}

.floatingPanel__background {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 2;
	width: 100dvw;
	height: 100dvh;
	transition: all var(--transition-base), height 0s, width 0s;
}

.floatingPanel {
	position: absolute;
	/* Same rationale as .overlayPanel above: slow rung + decelerating curve for a
	   full-surface entrance, `all` retained so themed paint still cross-fades. */
	transition: all var(--motion-slow) var(--ease-enter), height 0s, width 0s;
}

/* Horizontally center the contained panel within the full-width backdrop.
   Added by DisplayDialog only (overlays/side-panels keep edge alignment). */
.floatingPanel-centered {
	display: flex;
	justify-content: center;
}

/* Transitions */

/* Fade In — carries the same character as the .motion-enter treatment in
   utilities.css (opacity + a small rise), expressed as a class toggle because it
   rides the transition above rather than a keyframe. Safe from transform
   collisions: the fade variant is mutually exclusive with the four slide
   variants below (see TRANSITIONS in constants.js).
   The settled state is `transform: none`, NOT `translateY(0)` — any transform
   other than `none` makes this wrapper the containing block for its
   position: fixed descendants, and .floatingExpandablePanel__view is fixed
   precisely so its position-try-fallbacks resolve against the viewport. */
.floatingPanel-fadeOut {
	opacity: 0;
	transform: translateY(var(--motion-enter-distance));
}

.floatingPanel-fadeIn {
	opacity: 1;
	transform: none;
}

/* appear from top */

.floatingPanel-collapsed__top {
	top: 0;
	width: 100%;
	transform: translateY(-110vh);
}

.floatingPanel-expanded__top {
	transform: translateY(5rem);
}

/* Appear form Right */

.floatingPanel-collapsed__right {
	right: 0;
	top: 0;
	transform: translateX(110vw);
	height: 100dvh;
}

.mainView__floatingPanel__background {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 900;
	width: 100dvw;
	height: 100dvh;
	transition: all var(--transition-base), height 0s, width 0s;
}

.floatingPanel-expanded__right {
	transform: translateX(0);
}

/* Appear from Bottom */

.floatingPanel-collapsed__bottom {
	transform: translateY(110vh);
}

.floatingPanel-expanded__bottom {
	transform: translateY(0);
}

/* Appear from left */

.floatingPanel-collapsed__left {
	top: 0;
	left: 0;
	transform: translateX(-110vw);
	height: 100dvh;
}

.floatingPanel-expanded__left {
	transform: translateX(0);
	/* max-width: 75vw; */
}

.floatingPanel-collapsed__left--full {
	left: 0;
	transform: translateX(-110vw);
}

.floatingPanel-expanded__left--full {
	transform: translateX(0);
	max-width: 100dvw;
}

/**
* mainHeader.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2022-May-25 Initial Version
*/

.mainHeader__view {
	display: grid;
	grid-template-areas: 'mainHeader_entityArea mainHeader_searchField mainHeader_cartArea'
		'mainHeader_entityArea mainHeader_refreshArea mainHeader_cartArea';
	grid-template-columns: auto 1fr auto;
	align-items: center;
	justify-content: space-between;
	padding: 2rem 5rem 2rem 10rem;
	/* intentional literal: bespoke asymmetric header inset — the 10rem left leg clears the entity area's absolute chrome (no shell role is that wide) and the 2rem vertical sits between the --pad ladder rungs */
	width: 100%;
	overflow: visible;
	position: relative;
}

.mainHeader__cartArea {
	grid-area: mainHeader_cartArea;
	display: flex;
	align-items: center;
	justify-content: flex-end;
}

.mainHeader__invoiceCartIcon {
	margin-left: var(--gap-inline);
}

:root[data-viewport="phone"] .mainHeader__cartArea {
	position: fixed;
	top: 0.5rem;
	right: 0.5rem;
}

.mainHeader__entityArea {
	grid-area: mainHeader_entityArea;
}

.mainHeader__searchField {
	grid-area: mainHeader_searchField;
	margin: auto 0 0 auto;
}

.mainHeader__refreshAppContainer {
	grid-area: mainHeader_refreshArea;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
	margin-left: auto;
	cursor: pointer;
}

.mainHeader__refreshAppContainer__icon {
	height: 1.5rem;
	color: var(--text-secondary);
}

.mainHeader__refreshAppContainer__heading {
	color: var(--text-secondary);
}

:root[data-viewport="phone"] .mainHeader__refreshAppContainer {
	min-height: var(--touch-target-primary);
}

:root[data-viewport="phone"] .mainHeader__view {
	overflow: hidden;
	padding: 2rem 2rem 2rem 5rem;
	/* intentional literal: phone-band header inset — the 5rem left leg clears the entity chrome, the 2rem legs sit between the --pad ladder rungs */
}

/* 
.mainHeader__hamburger {
    grid-area: mainHeader_Left;
    margin: auto auto auto 5rem;
}

.mainHeader__showHamburger {
    z-index: 1;
}

.mainHeader__entityArea {
    grid-area: mainHeader_center;
    margin: auto;
    /* position: relative; */
/* justify-self: center;
} */

/* TODO: dead rules — nothing in the app emits any of the selectors from here to
   the end of the file (verified against every .js/.mjs/.html). Their literals are
   deliberately NOT tokenized; deleting the block is its own triplet. */

.mainHeader__controllers {
	grid-area: mainHeader_bottom_right;
	display: flex;
	justify-content: flex-end;
	padding-right: 4rem;
	color: var(--brand-accent);
}

.mainHeader__searchBar {
	grid-area: mainHeader_middle_right;
	width: 25rem;
	margin: auto;
}

.mainHeader__newEntityButton,
.mainHeader__searchButton {
	margin-right: 1rem;
}

.mainHeader__connectionIcon {
	grid-area: mainHeader_top_right;
	margin: 1rem 2rem auto auto;
}

.mainHeader__entitiesDropdown {
	display: flex;
	height: 10rem;
	max-height: 50vh;
	width: 10rem;
	max-width: 50vw;
	position: absolute;
	justify-self: center;
	margin-top: 13.5rem;
	z-index: 1;
	flex-direction: column;
	padding: 1rem;
	border: var(--brand-accent) 0.1rem solid;
	border-radius: var(--radius-button);
	background-color: var(--surface-page);
	overflow: scroll;
	transition: all var(--motion-slow) var(--ease-enter);
	overflow: visible;
}

/* TODO: this modifier is inert — `padding`/`max-height` are byte-identical to the
   base rule above, so opening the dropdown animates nothing. `overflow: scroll`
   in the base rule is also dead (overridden by `overflow: visible` two lines
   later). Both need the driving JS to set a real collapsed state first. */
.mainHeader__entitiesDropdown-expanded {
	padding: 1rem;
	max-height: 50vh;
}

.mainHeader__closeEntityDropdownButton {
	color: var(--surface-page);
	cursor: pointer;
	position: absolute;
	left: calc(100% - 1rem);
	bottom: -1rem;
	background: var(--surface-sunken);
	border-radius: var(--radius-circle);
	width: 2rem;
	height: 0rem;
}

.mainHeader__closeEntityDropdownButton-expanded {
	height: 2rem;
}

/**
* homePage.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-01-26 Initial Version
* @version 2026-May-26 Drop nav grid; remove dead sign-in / nav classes
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
*/

.homePage__view {
	width: 100dvw;
	height: 100dvh;
	/* intentional literal (inline axis): the landing page's deliberately wide 50px
	   gutter — there is no shell role that wide. The block axis takes --pad-page. */
	background-color: var(--surface-page);
	padding: var(--pad-page) 5rem;
	position: relative;
}

.homePage__leftPanel {
	height: calc(100dvh - 10rem);
	width: calc(40% - 5rem);
	margin: 5rem auto auto 0; /* intentional literal: positional (`auto`) panel pin, not spacing rhythm */
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: flex-start;
	position: absolute;
}

.homePage__rightPanel {
	height: calc(100dvh - 10rem);
	width: 100%;
	z-index: 2;
}

.homePage__imgContainer {
	width: 60%;
	height: calc(100dvh - 10rem);
	margin: 0 0 0 auto; /* intentional literal: positional (`auto`) right-align, not spacing rhythm */
	display: flex;
	align-items: center;
	justify-content: center;
	transition: opacity 0s;
}

.homePage__imgContainer:last-child {
	margin-bottom: 40vh; /* intentional literal: viewport-relative offset, not spacing rhythm */
}

.homePage__img {
	transition: opacity 0s;
	width: 100%;
}
/**
* selfEntityCalendarView.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-16 Initial Version
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

.selfEntityCalendarView__view {
	height: 100%;
	width: 100%;
}

.selfEntityCalendarView__collapsedContainer {
	width: 100%;
	padding: var(--pad-dense);
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
}

.selfEntityCalendarView__expandedContainer {
	width: 100%;
	padding: var(--pad-dense);
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
}

/**
* taskManagementCalendarView.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-16 Initial Version
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

.taskManagementCalendarView__view {
	height: 100%;
	width: 100%;
}

.taskManagementCalendarView__collapsedContainer {
	width: 100%;
	padding: var(--pad-dense);
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
}

.taskManagementCalendarView__expandedContainer {
	width: 100%;
	padding: var(--pad-dense);
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
}

/**
* dashboard.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing literal collapsed onto the app.css role tokens
*/

.dashboard__view {
	width: 100%;
	height: 100%;
}

.dashboard__view:has(.dashboard__tabHeaderBar) {
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
	grid-template-columns: minmax(0, 1fr);
	gap: var(--gap-stack);
}
/**
* selfEntityDashboard.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-January-13 Initial Version
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

.selfEntityDashboard__view {
	display: grid;
	gap: var(--gap-tile);
	grid-template-areas:
		"selfEntityDashBoard_entitiesBox selfEntityDashBoard_eventsBox selfEntityDashBoard_messagesBox"
		"selfEntityDashBoard_engagementBox selfEntityDashBoard_engagementBox selfEntityDashBoard_messagesBox";
	grid-template-columns: 1fr 1fr 1fr;
	grid-template-rows: 1fr 2fr;
	height: 100%;
	padding-right: var(--pad-card);
}

.selfEntityDashBoard__entitiesBox {
	grid-area: selfEntityDashBoard_entitiesBox;
}

.selfEntityDashBoard__eventsBox {
	grid-area: selfEntityDashBoard_eventsBox;
}

.selfEntityDashBoard__messagesBox {
	grid-area: selfEntityDashBoard_messagesBox;
}

.selfEntityDashBoard__engagementBox {
	grid-area: selfEntityDashBoard_engagementBox;
}
/**
* forgotPasswordView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
* @version 2026-August-14 Deleted the hardcoded light-mode gradient, the white field fill and the dead duplicate background: the shell renders unclassed markup, so no rule here has a consumer (#1840)
*/

.forgotPasswordView__view {
    display: grid;
    grid-template-rows: 18rem 6rem 1fr;
    gap: 2rem;
    height: 100dvh;
    width: 100dvw;
    justify-content: center;
    position: relative;
}

.forgotPasswordView__logo {
    height: 9rem;
    width: 31rem;
    align-self: end;
    justify-self: center;
}

.forgotPasswordView__resetPasswordString {
    text-align: center;
    height: fit-content;
    align-self: end;
}

.forgotPasswordView__pillbox {
    display: grid;
    grid-template-rows: auto auto 1fr;
    grid-gap: 2rem;
    height: fit-content;
    width: 40rem;
    justify-self: center;
}

.forgotPasswordView__submitButton {
    width: fit-content;
    margin-bottom: auto;
    justify-self: center;
}
/**
* tasksView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-02-18 Initial Version
* @version 2026-Jun-08 Rebuild on the ProjectsView layout
* @version 2026-Jun-22 Restore bucket height-containment — listColumn claims the grid cell + flexes the bucket
* @version 2026-June-30 Header row moved into the content grid above the bucket (mirrors ProjectsView); dropped the list-column aggregate strip
* @version 2026-June-30 Bucket width matches ProjectsView — proportional 1fr/2fr split instead of a fixed 25rem column
* @version 2026-June-30 Underline status-tab row + full-width Analytics row; the content container now scrolls
* @version 2026-June-30 Move the per-section track stack onto leftContainer so the bucket row stays height-bounded (fix bucket scroll after the leftContainer wrap)
* @version 2026-July-02 First-load skeleton stand-in for the bucket area
* @version 2026-July-29 Shell spacing collapsed onto the app.css role tokens; the
*   doubled page gutter (__view padding + __contentContainer padding) is now the
*   single --pad-page gutter on __contentContainer
*/

.tasksView__view {
	display: grid;
	gap: var(--gap-inline);
	height: 100%;
}

.tasksView__contentContainer {
	display: grid;
	grid-template-rows: minmax(0, 1fr);
	gap: var(--gap-section);
	overflow: hidden;
	background-color: var(--surface-card);
	border-radius: var(--radius-button);
	padding: var(--pad-page);
	position: relative;
}

.tasksView__contentContainer-sideBySide {
	grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}

.tasksView__statusTabs {
	max-width: 100%;
	justify-self: end;
	overflow-x: auto;
}

.tasksView__leftContainer {
	display: grid;
	grid-template-rows: auto auto auto auto minmax(0, 1fr);
	gap: var(--gap-stack);
	min-height: 0;
}

.tasksView__leftContainer>* {
	min-width: 0;
}

.tasksView__headingContainer {
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.tasksView__filtersContainer {
	width: 100%;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
	gap: var(--gap-inline);
	align-items: center;
}

.tasksView__searchBar {
	width: 100%;
}

.tasksView__picker {
	width: fit-content;
}

.tasksView__bucket {
	min-height: 0;
	padding-top: var(--gap-stack);
}

.tasksView__bucketSkeleton {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	padding-top: var(--gap-stack);
}

/**
* entitiesView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-March-04 Initial Version
* @version 2026-July-29 Shell spacing collapsed onto the app.css role tokens
*/
.entitiesView__view {
	height: 100%;
	min-height: 0;
	width: 100%;
	display: grid;
	grid-template-rows: auto 1fr;
	gap: var(--gap-stack);
}

.entitiesView__headingContainer {
	padding: var(--pad-row);
	display: flex;
	justify-content: start;
	align-items: center;
	gap: var(--gap-stack)
}

.entitiesView__searchBar {
	flex: 1;
}

.entitiesView__scrollArea {
	width: 100%;
	height: 100%;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(18rem, 100%), 1fr));
	align-content: start;
	gap: var(--gap-tile);
	border-radius: var(--radius-card);
	padding: var(--pad-cell);
}

.entitiesView__emptyMessage {
	grid-column: 1 / -1;
	text-align: center;
	color: var(--text-secondary);
	margin-top: var(--pad-shell);
}

.entitiesView__newEntityButton {}

.entitiesView__newEntityDialog {
	position: fixed;
	/* intentional literal: positional dialog offset from the viewport top, not spacing rhythm */
	top: 10rem;
	left: 50%;
	transform: translateX(-50%);
	padding: var(--pad-sheet);
}

/**
* clientsView.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-May-26 Initial Version
* @version 2026-May-29 Mirror ProjectsView layout (top container, status tabs row, bucket + panel side-by-side)
* @version 2026-July-04 Loading-bar row + first-load bucket skeleton (#15)
* @version 2026-July-29 Shell spacing collapsed onto the app.css role tokens; the
*   doubled page gutter (__view padding + __contentContainer padding) is now the
*   single --pad-page gutter on __contentContainer
*/
.clientsView__view {
	display: grid;
	grid-template-rows: minmax(0, 1fr);
	height: 100%;
}

.clientsView__contentContainer {
	display: grid;
	/* Two direct children (leftContainer + clientPanel) — a single bounded row so
	 * both fill the container height; the scrolling bucket lives in leftContainer. */
	grid-template-rows: minmax(0, 1fr);
	gap: var(--gap-section);
	overflow: hidden;
	background-color: var(--surface-card);
	border-radius: var(--radius-button);
	padding: var(--pad-page);
}

.clientsView__contentContainer-sideBySide {
	grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}

.clientsView__leftContainer {
	display: grid;
	grid-template-rows: auto auto minmax(0, 1fr);
	gap: var(--gap-stack);
	min-height: 0;
}

.clientsView__leftContainer>* {
	min-width: 0;
}

.clientsView__headingContainer {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-stack);
}

.clientsView__filtersContainer {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--gap-stack);
	justify-content: end;
}

.clientsView__searchBar {
	width: 100%;
}

.clientsView__toggleBar {
	max-width: 100%;
	overflow-x: auto;
}

.clientsView__bucket {
	min-height: 0;
	padding-top: var(--gap-stack);
}

/* First-load stand-in for the tile list — mirrors the endlessBucket__list
   spacing so the skeleton → bucket swap doesn't reflow (sibling convention:
   projectsView__bucketSkeleton). */
.clientsView__bucketSkeleton {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	padding-top: var(--gap-stack);
}

.clientsView__newClientPanel {
	width: min(80rem, calc(100% - 5rem));
}

/**
* searchView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Result-grid spacing collapsed onto the app.css role tokens —
*   the 5rem inter-result gap and 2rem/3rem margin were wasting the scroll surface
*/

.searchView__view {
	width: 100%;
	height: 100%;
	display: grid;
	grid-template-rows: 5rem minmax(0, 1fr);
	/* background-color: var(--surface-card);
    border: 1px solid var(--border-default);
    box-shadow: var(--elevation-raised);
    border-radius: var(--radius-card);
    backdrop-filter: blur(10px); */
}

.searchView__searchBarContainer {
	width: calc(100% - 55rem);
	margin: auto;
}

.searchView__searchBar {
	width: 100%;
}

.searchView__resultsScrollArea {
	height: 100%;
	width: 100%;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	gap: var(--gap-section);
	padding: var(--pad-page);
}

.searchView__closeButton {
	cursor: pointer;
}

:root[data-viewport="phone"] .searchView__searchBarContainer {
	width: calc(100% - 25rem);
	margin: auto auto 0 auto;
}

/**
* teamMembersView.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-09 Initial Version
* @version 2026-July-29 Shell spacing collapsed onto the app.css role tokens; the
*   doubled page gutter (__view padding + __contentContainer padding) is now the
*   single --pad-page gutter on __contentContainer
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
*/

.teamMembersView__view {
	display: grid;
	gap: var(--gap-stack);
	grid-template-rows: minmax(0, 1fr);
	height: 100%;
}

.teamMembersView__contentContainer {
	display: grid;
	grid-template-rows: minmax(0, 1fr);
	gap: var(--gap-section);
	overflow: hidden;
	background-color: var(--surface-card);
	border-radius: var(--radius-button);
	padding: var(--pad-page);
}

.teamMembersView__contentContainer-sideBySide {
	grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}

.teamMembersView__leftContainer {
	display: grid;
	grid-template-rows: auto auto minmax(0, 1fr);
	gap: var(--gap-stack);
	min-height: 0;
}

.teamMembersView__leftContainer>* {
	min-width: 0;
}

.teamMembersView__headingContainer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-stack);
}

.teamMembersView__searchBar {
	width: 100%;
}

.teamMembersView__bucket {
	min-height: 0;
	padding-top: var(--gap-stack);
}

.teamMembersView__addTeamMemberPanel {
	height: 75%;
	width: 50%;
}

:root[data-viewport="phone"] .teamMembersView__addTeamMemberPanel {
	height: 100dvh;
	width: 92vw;
	margin: 0;
}

/**
 * notifications.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2026-05-07 Initial Version
 * @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
 */

.notificationsView__view {
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
	width: 100%;
	height: 100%;
	padding: var(--pad-page);
}

/* TODO: dead rule — no emitter for this selector; its literal is deliberately NOT tokenized. */
.notificationsView__heading {
	margin-bottom: 1rem;
}

.notificationsView__emptyMessage {
	color: var(--text-secondary);
	text-align: center;
	margin-top: var(--pad-shell);
}

/**
* requestDetailView.css — the ActionRequest detail surface (#1457).
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-04 Initial Version
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

.requestDetailView__view {
	display: grid;
	grid-template-rows: auto auto auto 1fr;
	gap: var(--gap-inline);
	width: 100%;
	height: 100%;
	overflow: hidden;
}

.requestDetailView__header {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.requestDetailView__summary {
	display: flex;
	flex-direction: column;
	gap: var(--gap-tight);
	padding: var(--pad-dense);
	border-radius: var(--radius-card);
}

.requestDetailView__parties {
	font-weight: 600;
}

.requestDetailView__statusRow {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--gap-inline);
}

.requestDetailView__status {
	font-weight: 600;
}

.requestDetailView__status-action_request_status_accepted {
	color: var(--status-success);
}

.requestDetailView__status-action_request_status_rejected,
.requestDetailView__status-action_request_status_cancelled {
	color: var(--status-danger);
}

.requestDetailView__status-action_request_status_pending {
	color: var(--status-partial);
}

.requestDetailView__dates {
	color: var(--text-secondary);
}

.requestDetailView__actions {
	display: flex;
	gap: var(--gap-inline);
}

.requestDetailView__composer {
	display: flex;
	gap: var(--gap-inline);
	align-items: center;
}

.requestDetailView__composerInput {
	flex: 1;
}

.requestDetailView__unavailable {
	color: var(--text-secondary);
}

/**
* notePad.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
* @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
*/

.notePad__view {
    /* margin: 3rem 0 auto auto; */
    height: 100dvh;
    /* width: 70vw; */
    width: fit-content;
    background: var(--surface-page);
    display: grid;
    grid-template-areas: 'notePad__controlContainer' 'notePad__bodyContainer';
    grid-template-rows: auto 1fr;
    border-radius: var(--radius-button);
    box-shadow: var(--elevation-overlay);
}

.notePad__bodyContainer {
    display: grid;
    grid-template-areas: 'notePad__notesScrollArea notePad__noteContentscrollArea';
    margin: var(--gap-stack);
    padding: var(--pad-card);
    grid-template-columns: 22rem auto;
}

.notePad__notesScrollArea {
    grid-area: notePad__notesScrollArea;
}

.notePad__notesScrollArea-noBorder {
    border-right: transparent;
}

.notePad__noteContentscrollArea {
    grid-area: notePad__noteContentscrollArea;
}

.notePad__controlContainer {
    grid-area: notePad__controlContainer;
    margin: var(--gap-stack);
    display: grid;
    grid-template-areas: 'notePad__closeButton notePad__entityDropdown notePad__addNote';
    grid-template-columns: auto auto 1fr;
    align-items: center;
    gap: var(--gap-stack);
}

.notePad__closeButton {
    grid-area: notePad__closeButton;
    /* transform: scaleX(-1); */
}

.notePad__entityName {
    grid-area: notePad__entityDropdown;
    cursor: pointer;
    display: flex;
    align-items: center;
}

.notePad__dropdownArrow {
    width: 0;
    height: 0;
    border-top: .5rem solid transparent;
    border-bottom: .5rem solid transparent;
    /* intentional literal: 1px baseline nudge + the icon-gap on a CSS-triangle
       arrow whose size is set by the border legs above, not spacing rhythm. */
    border-left: 1rem solid var(--text-primary);
    margin-left: .5rem;
    margin-top: .1rem;
    cursor: pointer;
}

.notePad__dropdownArrow-expanded {
    transform: rotate(90deg);
}

.notePad__entitiesDropdown {
    top: 5rem;
    left: 4rem;
    max-height: 15rem;
}

.notePad__entitiesContainer {
    display: grid;
    gap: var(--gap-inline);
    padding: var(--pad-card);
    height: 100%;
}

.notePad__entitiesContainer>* {
    padding: var(--pad-dense);
    border-radius: var(--radius-button);
}

.notePad__entitiesContainer>*:hover {
    background-color: var(--surface-hover);
}

.notePad__addNote {
    grid-area: notePad__addNote;
    margin-left: auto;
    box-shadow: var(--elevation-overlay);
    border-radius: var(--radius-circle);
    background-color: var(--brand-accent);
    color: white;
    padding: var(--pad-dense);
    
}
.notePad__addNote:hover {
    transform: scale(1.02);
    box-shadow: var(--elevation-surround);
}

/**
* account.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-03 Rewritten for the rebuilt display-only Account view (#1252) —
*          the commented-out legacy edit-grid layout is gone.
* @version 2026-July-04 Delete-account danger zone + confirm-dialog layout (#1417)
* @version 2026-July-15 Edit-account action row + edit dialog layout (#1613)
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens; the
*          danger-zone rule's hairline now reads the declared --border-default token
*          (`--border-color` was never declared anywhere, so the rule always fell
*          through to a fixed 15%-black that is invisible on dark themes)
* @version 2026-August-21 Set-a-password dialog layout + the delete dialog's re-auth
*          toggle (invoice payer flow)
*/

.account__view {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--gap-tile);
	align-content: start;
	padding: var(--pad-page);
}

.account__title {
	margin: 0;
}

.account__row {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--gap-tight);
}

.account__rowValue {
	margin: 0;
	/* formatAddress joins address lines with \n */
	white-space: pre-line;
}

.account__skeleton {
	max-width: 32rem;
}

.account__dangerZone {
	display: grid;
	justify-items: start;
	margin-top: var(--gap-stack);
	padding-top: var(--gap-stack);
	border-top: var(--border-width) solid var(--border-default);
}

.account__dangerZone .button {
	min-height: 44px; /* intentional literal: #1641 primary touch floor — the destructive hold gesture needs a real target */
}

.account__deleteDialog {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--gap-stack);
	max-width: 28rem;
	padding: var(--pad-sheet);
}

.account__deleteDialogTitle,
.account__deleteDialogWarning {
	margin: 0;
}

.account__deleteDialogForm {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--gap-inline);
}

.account__deleteDialogButtons {
	display: flex;
	justify-content: flex-end;
	gap: var(--gap-inline);
}

.account__deleteDialogCodeToggle {
	justify-self: start;
}

.account__setPasswordDialog {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--gap-stack);
	max-width: 28rem;
	padding: var(--pad-sheet);
}

.account__setPasswordDialogTitle,
.account__setPasswordDialogHint {
	margin: 0;
}

.account__setPasswordDialogHint {
	font-size: var(--font-size-label);
	color: var(--text-secondary);
}

.account__setPasswordDialogForm {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--gap-inline);
}

.account__setPasswordDialogButtons {
	display: flex;
	justify-content: flex-end;
	gap: var(--gap-inline);
}

.account__actionRow {
	display: flex;
	justify-content: flex-start;
	gap: var(--gap-inline);
	margin-top: var(--gap-stack);
}

.account__editDialog {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--gap-stack);
	width: calc(100dvw - 10rem);
	min-width: 32rem;
	padding: var(--pad-sheet);
}

.account__editDialogTitle {
	margin: 0;
}

.account__editDialogForm {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--gap-stack);

	.headerWithSmallHeading__view {
		width: auto;
	}

	.emailFields__view {
		width: auto;

		>* {
			width: 100%;
		}
	}
}

.account__editDialogSection {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
	gap: var(--gap-inline);
	width: auto;
}

.account__editDialogHint {
	margin: 0;
	font-size: var(--font-size-label);
	color: var(--text-secondary);
}

.account__editDialogButtons {
	display: flex;
	justify-content: flex-end;
	gap: var(--gap-inline);
	align-items: center;
}

.account__editDialogPhoneFields {
	width: auto;
}

/**
 * invoices.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2020-04-16 Initial Version 
 * @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens.
 *   This file is the ROOMY page frame around the dense invoice/invoiceTable
 *   components — the tight rows live in those components' own CSS, not here.
 * @version 2026-August-04 Viewport layout units unified on dvh/dvw — the body/#root/app-shell chain disagreed (svh/vh/dvh) (#1822)
 */

.newInvoiceView__view {
    height: 100%;
    width: 100%;
    display: grid;
    grid-template-areas: 'invoices_headingContainer invoices_headingContainer'
        'invoices_controlls invoices_controlls'
        'invoices_intervalPicker invoices_intervalPicker'
        'newInvoiceView_panelContainer newInvoiceView_panelContainer'
        '. invoices_button';
    grid-template-rows: repeat(3, auto) 1fr auto;
    grid-template-columns: 1fr 1fr;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--gap-section);
    /* border: 1px solid; */
}

.newInvoiceView__headingContainer {
    grid-area: invoices_headingContainer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: var(--surface-sunken);
    padding: var(--pad-card) var(--pad-page);
    border-radius: var(--radius-button);
}

.newInvoiceView__clientName {
    text-transform: uppercase;
}

.newInvoiceView__controls {
    grid-area: invoices_controlls;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 var(--pad-page);
}

.newInvoiceView__filters {
    display: flex;
    align-items: center;
    gap: var(--gap-section);
}

.newInvoiceView__intervalPicker {
    grid-area: invoices_intervalPicker;
    padding: 0 var(--pad-card);
}

.newInvoiceView__previewButton {
    grid-area: invoices_button;
    margin: auto 1rem auto auto; /* intentional literal: positional (`auto`) margin, not spacing rhythm */
}

.newInvoiceView__previewButton-disabled {
    background-color: var(--surface-sunken);
    pointer-events: none;
}

.newInvoiceView__invoiceDateInput {
    width: 10rem;
}

.newInvoiceView_panelContainer {
    grid-area: newInvoiceView_panelContainer;
    display: grid;
    grid-template-rows: auto auto auto 1fr;
    gap: var(--gap-section);
}

.newInvoiceView__hourlyPanel, .newInvoiceView__monthlyPanel, .newInvoiceView__flatPanel {
    max-height: 50rem;
}

/* Panel-heading / tile styles moved to invoiceCompensationPanel.css with the
   InvoiceCompensationPanel extraction (#1087 purity rewrite). */

/* TODO: dead rule — no emitter for this selector; its literal is deliberately NOT tokenized. */
.newInvoiceView__pdfIframe__container {
    display: block;
    background-color: white;
    padding: 1rem;
    z-index: 2;
    height: calc(100dvh - 10rem);
    width: calc(100dvw - 10rem);
}

.newInvoiceView__pdfIframe {
    /* height: calc(100vh - 11rem);
    width: calc(100vw - 11rem); */
    height: 100%;
    width: 100%;
}

/* Invoice View */

.newInvoiceView__invoiceView {
    height: 100%;
    width: 100%;
    display: grid;
    /* padding: 5rem 5rem 0 5rem; */
    grid-template-areas: 'invoices_invoice_view invoices_invoice_view invoices_invoice_view invoices_invoice_view''newInvoiceView_invoiceView_downloadButton invoices_invoice_saveButton invoices_invoice_emailPicker invoices_invoice_sendButton';
    grid-template-rows: 1fr auto;
    grid-template-columns: 1fr auto auto auto;
    background: var(--surface-page);
}

.newInvoiceView__invoice__view {
    grid-area: invoices_invoice_view;
}
.newInvoiceView__invoiceView__downloadButton{
    grid-area: newInvoiceView_invoiceView_downloadButton;
    margin: 2rem 2rem 4rem auto; /* intentional literal: positional (`auto`) margin, not spacing rhythm */
}
.newInvoiceView__invoiceView__sendButton {
    grid-area: invoices_invoice_sendButton;
    margin: 2rem 2rem 4rem auto; /* intentional literal: positional (`auto`) margin, not spacing rhythm */
}

.newInvoiceView__invoiceView__emailPicker {
    grid-area: invoices_invoice_emailPicker;
    margin: auto 0 4rem auto; /* intentional literal: positional (`auto`) margin, not spacing rhythm */
}

.newInvoiceView__invoiceView__saveButton {
    grid-area: invoices_invoice_saveButton;
    margin: 2rem 2rem 4rem auto; /* intentional literal: positional (`auto`) margin, not spacing rhythm */
}
/**
 * invoiceCompensationPanel.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2026-July-02 Initial Version — NewInvoiceView purity rewrite (#1087)
 * @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens; the
 *   repeating compensation tile takes the §Dense set (row-repeating list surface)
 */

/* Shell duplicated from headerWithExpandableScrollArea.css (locked decision:
   HWESA stays untouched) + the header-row styles that lived on
   .newInvoiceView__panelHeading before the rewrite. */

.invoiceCompensationPanel__view {
    display: grid;
    width: 100%;
    height: 100%;
}

.invoiceCompensationPanel__headerContainer {
    width: 50%;
    margin: auto auto auto 0; /* intentional literal: positional (`auto`) margin, not spacing rhythm */
    padding: var(--pad-card) var(--pad-card) 0 var(--pad-card);
    display: flex;
    align-items: center;
    gap: var(--gap-stack);
    cursor: pointer;
    text-align: left;
}

/* The class is stamped in JS (InvoiceCompensationPanel.js:101) but had no rule.
   It is a `getHeading`, so it inherited `--font-display` — a money total in the
   theme's display face. Body face + tabular figures, like every other money
   surface. */
.invoiceCompensationPanel__total {
    font-family: var(--font-body);
    font-variant-numeric: tabular-nums;
}

.invoiceCompensationPanel__totalPlaceholder {
    width: 8rem;
}

.invoiceCompensationPanel__arrow {
    fill: var(--text-primary);
    width: 1.5rem;
    margin: auto 0 auto auto; /* intentional literal: positional (`auto`) margin, not spacing rhythm */
    transition: all var(--motion-fast) var(--ease-standard);
}

.invoiceCompensationPanel__arrow-rotated {
    transform: rotate(-180deg);
}

.invoiceCompensationPanel__scrollAreaContainer {
    max-height: 0;
    overflow: hidden;
}

/* TODO: `max-height: inherit` resolves to the parent's `none`, which is not an
   animatable endpoint, so this expand snaps no matter how it is timed. Needs a
   JS-measured pixel height (or a grid-template-rows 0fr→1fr reveal). */
.invoiceCompensationPanel__scrollAreaContainer-expanded {
    max-height: inherit;
}

.invoiceCompensationPanel__scrollArea {
    padding: var(--pad-card);
}

/* dense data surface: --pad-dense/--gap-dense per the token contract's §Dense
   exception — this tile repeats once per compensation row. */
.invoiceCompensationPanel__tile {
    margin: var(--gap-dense) 0;
}

/**
* receivedInvoices.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-21 Initial Version (invoice payer flow)
* @version 2026-August-22 The row + status-chip rules move to receivedInvoiceRow.css with the row
*          markup, and the view's own list/skeleton rules give way to the EndlessBucket (#1973/#1979)
* @version 2026-August-22 The endlessBucket__list reach dropped (review 3736): gap sits in the
*          "parent must not set" column and the deeper-than-.view reach was swept in #1090 —
*          the bucket's own list spacing stands
*/

.receivedInvoicesView__view {
	display: grid;
	grid-template-rows: auto 1fr;
	gap: var(--gap-stack);
	padding: var(--pad-page);
	height: 100%;
	min-height: 0;
}

.receivedInvoicesView__detail {
	display: grid;
	gap: var(--gap-stack);
	align-content: start;
	padding: var(--pad-page);
}

.receivedInvoicesView__detailRow {
	display: grid;
	gap: var(--gap-dense);
}

.receivedInvoicesView__detailLabel {
	color: var(--text-secondary);
}

/**
 * activityModule.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2026-July-21 Initial Version — split from the retired performanceModule.css during
 *          the Performance→Activity rename; mirrors TasksView/ProjectsView/ClientsView with an
 *          outer contentContainer (Foreground bg + rounded), a pillBox left rail track-stacking
 *          heading · date-picker · member dropdown · summary · graph, and a pillBox right rail
 *          for the date-tile list (#1730)
 * @version 2026-July-29 Shell spacing collapsed onto the app.css role tokens; the
 *          doubled page gutter (__view padding + __contentContainer padding) is now
 *          the single --pad-page gutter on __contentContainer, and __rightContainer's
 *          bespoke `overflow-y: auto` is replaced by the shared `.scrollArea` class
 */

.activityModule__view {
	display: grid;
	gap: var(--gap-inline);
	height: 100%;
}

.activityModule__contentContainer {
	display: grid;
	grid-template-rows: minmax(0, 1fr);
	gap: var(--gap-section);
	overflow: hidden;
	background-color: var(--surface-card);
	border-radius: var(--radius-button);
	padding: var(--pad-page);
}

.activityModule__contentContainer-sideBySide {
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.activityModule__leftContainer {
	display: grid;
	grid-template-rows: auto auto auto auto minmax(0, 1fr);
	gap: var(--gap-stack);
	min-height: 0;
}

.activityModule__leftContainer>* {
	min-width: 0;
}

.activityModule__headingContainer {
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.activityModule__datePicker {
	width: 100%;
}

.activityModule__datePicker .fromToDatePicker__sideBySideContainer-expanded {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	z-index: 10;
	background: var(--surface-card);
	border-radius: var(--radius-button);
	box-shadow: var(--elevation-raised);
	padding: var(--pad-card);
	max-height: none;
}

.activityModule__graphContainer {
	min-height: 0;
	min-width: 0;
	display: flex;
}

.activityModule__graph {
	height: 100%;
	width: 100%;
}

/* Fills its parent whether that's the sideBySide grid track (desktop) or the
   full-viewport overlayPanel (mobile "View Intervals" button). */
.activityModule__rightContainer {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	height: 100%;
	min-height: 0;
}

/**
* messages.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-07-15 Initial Version
* @version 2026-July-03 Drop the dead .messages__numberOfChatsWithUnreadMsgsHeading rule — its Messages.js consumer namespace was retired (#1253)
* @version 2026-July-04 Three-column modifier for the open thread panel (#1454)
* @version 2026-July-29 Live spacing literals collapsed onto the app.css role tokens;
*   the three emitterless rules keep theirs (see the TODO below)
*/

.messagesView__view {
	height: 100%;
	width: 100%;
	display: grid;
	grid-template-columns: 2fr 3fr;
	grid-template-areas: 'messagesView__leftColumn messagesView__rightColumn';
}

/* Messages View */

/* .messagesView__view:before{
    content: "";
    position: absolute;
    background: currentColor;
    height: 3.4rem;
    width: 0.1rem;
    right: 0.6rem;
    top: -0.48rem;
    transform: rotate(-45deg);
} */

.messagesView__leftColumn {
	grid-area: messagesView__leftColumn;
	display: grid;
	grid-template-areas: 'messagesView__HeadingArea' 'messagesView__entitiesDropdownContainer' 'messagesView__leftScrollArea';
	width: 100%;
	gap: var(--gap-stack);
	grid-auto-rows: 3rem 2rem 1fr;
	overflow: hidden;
}

.messagesView__HeadingArea {
	grid-area: messagesView__HeadingArea;
	/* display: flex;
    justify-content: space-between; */
	display: grid;
	/* grid-template-areas: 'messagesView__heading messagesView__addButton' 'messagesView__entitiesDropdownContainer messagesView__entitiesDropdownContainer'; */
	grid-template-areas: 'messagesView__heading messagesView__addButton';
	padding: 0 var(--pad-card);
	align-items: center;
}

.messagesView__heading {
	/* width: auto; */
	grid-area: messagesView__heading;
}

.messagesView__addButton {
	grid-area: messagesView__addButton;
}

/* TODO: dead rules — nothing emits .messagesView__entitiesDropdownContainer,
   .messagesView__entityName or .messagesView__dropdownArrow*; their literals are
   deliberately NOT tokenized. Deleting them is its own triplet. */
.messagesView__entitiesDropdownContainer {
	grid-area: messagesView__entitiesDropdownContainer;
	margin-right: auto;
	padding-left: 1.5rem;
	display: flex;
	align-items: center;
	/* grid-template-areas: 'messagesView__entityName' 'messagesView__entitiesDropdown'; */
	position: relative;
}

.messagesView__entityName {
	grid-area: messagesView__entityName;
	cursor: pointer;
}

.messagesView__dropdownArrow {
	width: 0;
	height: 0;
	border-top: .5rem solid transparent;
	border-bottom: .5rem solid transparent;
	border-left: 1rem solid var(--text-primary);
	margin-left: .5rem;
	margin-top: .1rem;
	cursor: pointer;
}

.messagesView__dropdownArrow-expanded {
	transform: rotate(90deg);
}

.messagesView__entitiesDropdown {
	width: auto;
	margin: 0 var(--gap-stack);
	/* grid-area: messagesView__entitiesDropdown; */
	/* top: 2rem; */
}

.messagesView__leftScrollArea {
	/* grid-area: messagesView_leftScroll; */
	/* min-width: 30vw; */
	padding: 0 var(--pad-card);
}

.messagesView__rightColumnContainer {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	contain: size;
}

.messagesView__rightColumn {
	grid-area: messagesView__rightColumn;
	/* padding: 1.5rem 1.5rem 0 1.5rem; */
	display: block;
	height: calc(100% - 3rem);
	padding-left: var(--pad-card);
}

.messagesView__chatHeading {
	flex: none;
}

.messagesView__rightColumnFeedback {
	margin-top: var(--gap-section);
}
/* Threads (#1454): third column when a thread panel is open (desktop). */

.messagesView__view-threadOpen {
	grid-template-columns: 2fr 3fr 3fr;
	grid-template-areas: 'messagesView__leftColumn messagesView__rightColumn messagesView__threadColumn';
}

/**
* chat.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-03-10 Initial Version
* @version 2026-July-03 Prune retired InvitationChatView rules (#671)
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

.chatView__view {
	display: grid;
	grid-template-rows: 1fr 3rem;
	grid-template-columns: 1fr;
	row-gap: var(--gap-stack);
	height: 100%;
	contain: size;
}

.chatView__buttonArea {
	display: flex;
	align-items: center;
	justify-content: flex-end;
}

/* TODO: dead rule — no emitter for this selector; its literal is deliberately NOT tokenized. */
.chatView__buttonArea>* {
	margin: auto 1rem auto 0;
}

.chatView__controllers {
	grid-row: -2 / -1;
	display: grid;
	grid-template-columns: 1fr auto;
	gap: var(--gap-stack);
	align-items: center;
	justify-content: center;
	padding: 0 var(--pad-card);
	contain: inline-size;
}

.chatView__input {
	margin: auto;
	min-width: 0;
	/* Deliberate progressive-enhancement cascade, NOT a shadowed duplicate: each
	   engine keeps the last value it understands (`stretch` is the standard name,
	   `-moz-available`/`-webkit-fill-available` the older vendor spellings). */
	max-width: -webkit-fill-available;
	max-width: -moz-available;
	max-width: stretch;
}

.chatView__sendButton {
	height: 100%;
}

.chatView__sendButtonImage {
	height: 100%;
	width: auto;
	margin: auto;
	cursor: pointer;
}

.chatView__scrollArea {
	display: flex;
	flex-direction: column;
	grid-row: span 1;
	align-content: end;

	&>* {
		flex: none;
	}
}
/**
* threadSidePanel.css — the chat thread side panel (#1454).
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-04 Initial Version
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

/* dense data surface: --pad-dense/--gap-dense/--radius-dense per the token
   contract's §Dense exception — the thread tile is a row-repeating list row. */

.threadSidePanel__view {
	height: 100%;
	width: 100%;
	display: grid;
	grid-template-rows: 3rem minmax(6rem, 30%) 1fr;
	gap: var(--gap-dense);
	overflow: hidden;
	border-left: 1px solid var(--border-default);
	padding-left: var(--pad-dense);
}

.threadSidePanel__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0 var(--pad-dense);
}

.threadSidePanel__list {
	padding: 0 var(--pad-dense);
}

.threadSidePanel__threadTile {
	display: flex;
	width: 100%;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--gap-dense);
	padding: var(--pad-dense);
}

.threadSidePanel__threadTile-selected {
	background: var(--surface-selected);
}

.threadSidePanel__threadTilePreview {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.threadSidePanel__threadTileCount {
	flex: none;
	color: var(--text-secondary);
	font-size: smaller; /* intentional literal: relative keyword, not a scale step */
}

/**
 * about.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2020-12-01 Initial Version 
 * @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
 */

.aboutView__view {
    display: grid;
    grid-template-columns: 20rem 1fr;
    height: 100%;
}

.aboutView__leftPanel {
    height: calc(100% - 2rem);
    padding-right: var(--pad-page);
    margin: var(--gap-stack);
    display: grid;
    gap: var(--gap-stack);
    align-items: center;
    grid-template-rows: repeat(6, 2rem);
    border-color: var(--brand-accent);
}

.aboutView__noContentMsg {
    width: fit-content;
    margin-top: 5rem; /* intentional literal: empty-state drop from the view top, no role at 48px+ */
    height: fit-content;
    justify-self: center;
    grid-column: 1/3;
}
/**
* newContentTabView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-04-16 Initial Version
* @version 2026-July-29 Shell padding collapsed onto the app.css role tokens
*/

.newContentTabView__view {
    display: grid;
    height: 100%;
    width: 100%;
    grid-template-rows: 3rem 1fr;
    padding: var(--pad-shell);
}
/**
* contactView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

.contactView__view{
    display: grid;
    height: 100%;
    grid-template-rows: auto 1fr;
}
.contactsView__scrollArea{
    padding: var(--pad-page);
    width: 100%;
    height: 100%;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    /* justify-content: center; */
    align-content: flex-start;
    gap: var(--gap-tile);
}

.contactView__noContactsMsg {
    margin-top: var(--gap-section);
}
/**
* webContentBuilder.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2021-04-16 Initial Version
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

.webContentBuilder__view {
    padding: var(--pad-page);
    display: grid;
    grid-template-columns: 17rem 1fr;
}

.webContentBuilder__leftPanel {
    padding: var(--pad-card);
    display: grid;
    gap: var(--gap-stack);
    grid-auto-rows: min-content;
    justify-content: left;
}

.webContentBuilder__rightPanel {
    padding: var(--pad-card);
    display: grid;
    gap: var(--gap-stack);
    grid-auto-rows: min-content;
}

.webContentBuilder__addButton {
    transition: all var(--motion-fast) var(--ease-standard);
    box-shadow: var(--elevation-overlay);
    border-radius: var(--radius-circle);
    background-color: var(--brand-accent);
    color: white;
    padding: var(--pad-dense);
    margin-bottom: auto;
    margin-left: auto;
    margin-top: var(--gap-stack);
}

.webContentBuilder__addButton:hover {
    transform: scale(1.02);
    box-shadow: var(--elevation-surround);
}

.webContentBuilder__newContentNodePanel {
    color: var(--text-primary);
}

.webContentBuilder__newContentNodePanel>* {
    padding: var(--pad-dense) var(--pad-card) 0 var(--pad-card);
    border-radius: var(--radius-button);
    cursor: pointer;
}

.webContentBuilder__newContentNodePanel>*:hover {
    background-color: var(--surface-hover);
}

.webContentBuilder__draggedNode-hoverOver:before {
    content: '';
    width: 100%;
    height: .2rem;
    background-color: var(--brand-accent);
    transform: translateY(-15px);
    border-radius: var(--radius-card);
}

/* Web Content Tile */

.webContentTile__view {
    margin: 0;
    display: grid;
    width: 100%;
    height: fit-content;
    border-radius: var(--radius-button);
}

/* Edit Webcontent Tile */

.editWebContentTile__view {
    display: grid;
}

.editWebContentTile__elementEditView {
    height: 13rem;
    display: flex;
    justify-content: space-between;
    flex-direction: column;
}

.editWebcontentTile__backgroundToggleBar {
    /* margin: .5rem auto auto -.5rem; */
    grid-template-columns: auto auto auto;
    margin: 0;
}

.editWebcontentTile__imagePicker {
    /* height: 2rem;
    width: auto; */
    width: 3rem;
}

.editWebContentTile__deleteButton {
    text-align: left;
}

/**
* connectionError.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-03 Header backfilled (#605)
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

.connectionError__view {
    width: fit-content;
    background: var(--surface-page);
    margin: 10rem auto auto 50vw; /* intentional literal: positional viewport-centring anchor (paired with translateX(-50%)), not spacing rhythm */
    transform: translateX(-50%);
    box-shadow: var(--elevation-overlay);
    display: grid;
    gap: var(--gap-stack);
}
/**
* editableProfilePreview.css
* @author Miguel A. González <miguel.gonzalez@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved
*
* @version 2023-September-05 Initial Version
*/

.editableProfilePreview__view{
    width: 100%;
    height: 100%;
}

.editableProfilePreview__profile{
    width: 100%;
    height: 100%;
}
/**
 * teamMemberTasks.css
 * @author Edwin X. Borrero <edwin.borrero@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2023-09-13 Initial Version 
 * @version 2026-July-29 The repeating task-entry tile takes the §Dense set
 */
 .teamMemberTasks__view{
    height: 100%;
    width: 100%;
 }
 /* dense data surface: --pad-dense/--gap-dense per the token contract's §Dense
    exception — this tile repeats once per task row. */
 .teamMemberTasks__taskEntryTile{
    margin: var(--gap-dense);
 }
/**
* glitchContainer.css
* @author Raúl E. Barroso <raulbarroso@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2023-09-14 Initial Version
*/

.glitchContainer {
    position: relative;
    display: block;
    width: 100%;
}

.glitchContainer__clone, .glitchContainer__node {
    position: absolute;
    top: 0;
}

.glitchContainer-default .glitchContainer__clone {
    animation: glitch-effect 2.5s;
}

.glitchContainer-default .glitchContainer__node {
    animation: glitch-base 2.5s;
}

.glitchContainer-onHover:hover .glitchContainer__clone {
    animation: glitch-effect 2.5s;
}

.glitchContainer-onHover:hover .glitchContainer__node {
    animation: glitch-base 2.5s;
}

.glitchContainer-default.glitchContainer-infinite .glitchContainer__clone,
.glitchContainer-default.glitchContainer-infinite .glitchContainer__node {
    animation-iteration-count: infinite;
}

.glitchContainer-onHover.glitchContainer-infinite:hover .glitchContainer__clone,
.glitchContainer-onHover.glitchContainer-infinite:hover .glitchContainer__node {
    animation-iteration-count: infinite;
}


@keyframes glitch-effect {
    0%, 2.9% {
        transform: translate(4px, 0px);
        clip-path: inset(0 0 75%);
        text-shadow: var(--brand-accent) -1px 0;
    }
    3%, 6.9% {
        transform: translate(-5px, 0px);
        clip-path: inset(40% 0 30%);
        text-shadow: var(--brand-accent) -1px 0, var(--text-secondary) 1px 0;
    }
    7%, 15.9% {
        transform: translate(0px, 0px);
        clip-path: none;
    } 
    16%, 19.9% {
        transform: translate(3px, 0px);
        clip-path: inset(80% 0 0);
        text-shadow: var(--text-secondary) 1px 0;
    } 
    20%, 100% {
        transform: translate(0px, 0px);
        clip-path: none;
    }
}

@keyframes glitch-base {
    0%, 2.9% {
        clip-path: inset(25% 0 0);
    }
    3%, 6.9% {
        clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 0 70%, 100% 70%, 100% 40%, 0% 40%);
    }
    7%, 15.9% {
        clip-path: none;
    } 
    16%, 19.9% {
        clip-path: inset(0 0 20%);
    } 
    20%, 100% {
        clip-path: none;
    }
}
/**
* propertiesModule.css
* @author Miguel A. González <miguel.gonzalez@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2025-October-03 Initial Version
*/

.propertiesModule__view {
	height: 100%;
	width: 100%;
	display: grid;
	grid-template-rows: 1fr auto;
}

.propertiesModule__addPropertyButton {
	justify-self: end;
}
/**
* membersModule.css
* @author Miguel A. González <miguel.gonzalez@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2025-October-03 Initial Version
*/

.membersModule__view {}
/**
* chat.css
* @author Edwin X. Borrero <edwin.borrero@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-02-24 Initial Version
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
* @version 2026-August-04 Panel width onto the dynamic viewport unit (#1822)
*/

.newChatView__view {
	width: calc(100dvw - 10rem);
	display: grid;
	gap: var(--gap-section);
	padding: var(--pad-card);
	background-color: var(--surface-card);
	border-radius: var(--radius-button);
	margin: 10vh auto auto 5rem; /* intentional literal: positional (`vh` + `auto`) panel anchor, not spacing rhythm */
}

/* .newChatView__view-cyber {
	width: calc(100dvw - 10rem);
	display: grid;
	grid-template-areas: 'newChatView__selectedEntityTile' 'newChatView__membersChooser' 'newChatView__controllers';
	gap: 2rem;
	padding: 1rem;
	background-color: var(--surface-card);
	border-radius: var(--radius-button);
	margin: 10vh auto auto 5rem;
	backdrop-filter: var(--surface-blur);
	box-shadow: 0px 0px 20px 0px var(--text-secondary);
} */

.newChatView__selectEntityContainer {
	display: flex;
	gap: var(--gap-stack);
	align-items: center;
	margin: auto;
}

/* .newChatView__membersChooser {} */

.newChatView__controllers {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: var(--gap-stack);
	align-items: center;
}

.newChatView__sendButton {
	height: 2rem;
	width: 2rem;
	cursor: pointer;
}

/**
* newProjectPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-March-18 Initial Version
* @version 2026-June-10 Add-client affordance row
* @version 2026-July-03 Size the add-client dialog panel (mirrors ClientsView) so the
*                       suggested-entities drawer sits within the panel's own box (#1207)
* @version 2026-July-03 Edit-mode project-image row (#1051)
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

.newProjectPanel__newClientPanel {
	width: 50%;
}

.newProjectPanel__imageHeading {
	text-align: left;
}

.newProjectPanel__imageRow {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.newProjectPanel__clientRow {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
}

.newProjectPanel__clientRow>.dropdown__view {
	flex: 1;
}

.newProjectPanel__view {
	display: grid;
}

.newProjectPanel__heading {
	text-align: left;
}

.newProjectPanel__inputContainer {
	padding-top: var(--gap-stack);
	display: grid;
	gap: var(--gap-stack);
}

.newProjectPanel__rateContainer {
	display: grid;
	gap: var(--gap-stack);
	align-items: end;
	grid-template-columns: 1fr 1fr 1fr;
}

.newProjectPanel__rateTypeDropdown,
.newProjectPanel__roundingTypeDropdown,
.newProjectPanel__rateInput {
	width: 100%;
	justify-self: stretch;
}

.newProjectPanel__deadlineHeading {
	text-align: left;
}

.newProjectPanel__clientDropdown {
	width: 100%;
}

.newProjectPanel__buttonsContainer {
	padding-top: var(--gap-stack);
	display: flex;
	justify-content: end;
	gap: var(--gap-stack);
}

:root[data-viewport="phone"] .newProjectPanel__view {
	width: 92vw;
}

:root[data-viewport="phone"] .newProjectPanel__newClientPanel {
	width: 100%;
}

/**
* projectsView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-April-01 Initial Version
* @version 2026-July-01 Mirror TasksView: heading + search + client dropdown + status toggle + bucket
*          stacked inside a pillBox left rail; single bounded content row; panel beside on desktop.
* @version 2026-July-02 First-load skeleton stand-in for the bucket area
* @version 2026-July-29 Shell spacing collapsed onto the app.css role tokens; the
*   doubled page gutter (__view padding + __contentContainer padding) is now the
*   single --pad-page gutter on __contentContainer
*/
.projectsView__view {
	display: grid;
	gap: var(--gap-inline);
	height: 100%;
}

.projectsView__contentContainer {
	display: grid;
	/* Two direct children (leftContainer + projectPanel) — a single bounded row so both fill
	 * the height; the left rail's own track stack holds the scrolling bucket. */
	grid-template-rows: minmax(0, 1fr);
	gap: var(--gap-section);
	overflow: hidden;
	background-color: var(--surface-card);
	border-radius: var(--radius-button);
	padding: var(--pad-page);
}

.projectsView__contentContainer-sideBySide {
	grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}

/* Left rail (pillBox, like TasksView): heading · search · client dropdown · status toggle ·
 * bucket. Only the bucket row flexes so it scrolls while the controls above stay put. */
.projectsView__leftContainer {
	display: grid;
	grid-template-rows: auto auto auto auto minmax(0, 1fr);
	gap: var(--gap-stack);
	min-height: 0;
}

.projectsView__leftContainer>* {
	min-width: 0;
}

.projectsView__headingContainer {
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.projectsView__filtersContainer {
	display: flex;
	align-items: center;
	justify-content: space-between;

}

.projectsView__searchBar {
	width: 100%;
}

.projectsView__clientFilter {
	width: 100%;
}

.projectsView__statusTabs {
	max-width: 100%;
	justify-self: end;
	overflow-x: auto;
}

.projectsView__bucket {
	min-height: 0;
	padding-top: var(--gap-stack);
}

/* First-load stand-in for the tile list — mirrors the endlessBucket__list
   spacing so the skeleton → bucket swap doesn't reflow. */
.projectsView__bucketSkeleton {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	padding-top: var(--gap-stack);
}

/**
* signInPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-May-26 Initial Version
* @version 2026-July-17 Phone rules re-gated :root[data-mobile] → :root[data-viewport="phone"] (decision 0004 phase 1, #1684)
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
* @version 2026-August-21 Flow-links stack (invoice payer flow) — the second sign-in
*          door's link joins Forgot Password in one column beside the submit button
*/

.signInPanel__view {
	align-items: baseline;
	justify-content: center;
	background: var(--surface-page);
}

.signInPanel__tabs {
	margin: auto;
}

.signInPanel__body {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
}

.signInPanel__buttons {
	display: grid;
	grid-template-columns: 1fr 1fr;
}

.signInPanel__flowLinks {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--gap-inline);
}

/* TODO: dead rule — no emitter for this selector; its literal is deliberately NOT tokenized. */
.signInPanel__forgotPasswordButton {
	margin-left: .5rem;
}

.signInPanel__signInButton {
	margin-right: var(--gap-inline);
}

/**
 * invoicePayOverlay.css — the public invoice overlay: the shared invoice.css
 * document plus the pay area under it (the pay-area shapes migrated from the
 * retired standalone page's publicInvoice.css).
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2026-August-21 Initial Version (invoice payer flow)
 */

.invoicePayOverlay__view {
    display: flex;
    flex-direction: column;
    gap: var(--gap-stack);
    height: 100%;
    overflow-y: auto;
    overflow-x: auto;
}

.invoicePayOverlay__skeleton {
    display: flex;
    flex-direction: column;
    gap: var(--gap-stack);
    padding: var(--pad-card);
}

.invoicePayOverlay__unavailable {
    padding: var(--pad-page);
    text-align: center;
}

.invoicePayOverlay__paidBanner {
    background: var(--status-success);
    color: var(--text-on-status);
    border-radius: var(--radius-card);
    padding: var(--pad-card);
    text-align: center;
    font-size: var(--font-size-lead);
}

.invoicePayOverlay__payArea {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--gap-stack);
    padding: var(--pad-card) var(--pad-page) var(--pad-page);
}

.invoicePayOverlay__payButton,
.invoicePayOverlay__claimButton {
    min-height: var(--touch-target-primary);
    min-width: 200px;
}

.invoicePayOverlay__claimNotice {
    text-align: center;
}

.invoicePayOverlay__payMessage {
    text-align: center;
    min-height: 1em;
}

.invoicePayOverlay__payArea .stripeElementsHost__view {
    width: 100%;
    max-width: 480px;
}

/**
 * payerChooser.css — the payer-identity step inside the invoice pay overlay:
 * the three-door toggle and each door's body (disclosure copy, ride-along
 * email field, inline sign-in panel).
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2026-August-21 Initial Version (invoice payer flow)
 */

.payerChooser__view {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--gap-stack);
    width: 100%;
    max-width: 480px;
}

.payerChooser__disclosure {
    text-align: center;
    color: var(--text-secondary);
}

.payerChooser__rideAlong {
    display: flex;
    flex-direction: column;
    gap: var(--gap-stack);
    width: 100%;
}

/**
* newTaskPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-April-09 Initial Version
*/

.newTaskPanel__view {
	display: block;
	width: min(46rem, 92vw);
}

.newTaskPanel__form {
	display: grid;
	grid-template-rows: auto minmax(0, 1fr) auto;
	gap: var(--gap-stack);
	max-height: 80vh;
	min-height: 0;
}

.newTaskPanel__heading {
	text-align: left;
}

.newTaskPanel__body {
	min-height: 0;
	padding-top: var(--gap-stack);
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--gap-tile);
	align-content: start;
}

.newTaskPanel__card {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	align-items: stretch;
	padding: var(--pad-card);
	background: var(--surface-sunken);
	border: var(--border-width) solid var(--border-default);
	border-radius: var(--radius-card);
}

.newTaskPanel__card-full {
	grid-column: 1 / -1;
}

.newTaskPanel__cardHeading {
	text-align: left;
	color: var(--text-secondary);
}

.newTaskPanel__taskTypeContainer {
	position: relative;
}

.newTaskPanel__taskTypeContainer>.dropdownTextField__view {
	width: 100%;
}

.newTaskPanel__taskTypeIndicator {
	position: absolute;
	top: 0;
	right: .5rem;
	display: flex;
	align-items: center;
	pointer-events: none;
}

.newTaskPanel__rateContainer {
	display: grid;
	gap: var(--gap-stack);
	align-items: end;
	grid-template-columns: 1fr 1fr;
}

.newTaskPanel__rateTypeDropdown,
.newTaskPanel__rateInput {
	width: 100%;
	justify-self: stretch;
}

.newTaskPanel__deadlineContainer {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	align-items: start;
}

.newTaskPanel__relationRow {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--gap-inline);
	align-items: end;
}

.newTaskPanel__projectRow {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: var(--gap-inline);
	align-items: center;
}

.newTaskPanel__deadlineHeading {
	text-align: left;
}

.newTaskPanel__projectDropdown,
.newTaskPanel__parentTaskDropdown,
.newTaskPanel__dependencyPicker,
.newTaskPanel__taskTypeDropdown {
	width: 100%;
}

.newTaskPanel__dependencyContainer {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	align-items: stretch;
}

.newTaskPanel__buttonsContainer {
	display: flex;
	align-items: center;
	justify-content: end;
	gap: var(--gap-stack);
}

:root[data-viewport="phone"] .newTaskPanel__body,
:root[data-viewport="phone"] .newTaskPanel__relationRow {
	grid-template-columns: 1fr;
}

/**
 * intervalTile.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2020-04-07 Initial Version
 * @version 2026-July-03 Bulk-selection checkbox (#896); the modal-only
 *          .intervalTile__editPanel rule pruned with the dialog flow it styled
 *          (the editor now expands in place inside the tile)
 * @version 2026-July-17 Hover-reveal gated to hover-capable devices — touch sees the edit/delete buttons always (#1641)
 * @version 2026-July-29 Design-system adoption — spacing/type/radius literals collapsed onto the role-token ladder
 */

.intervalTile__view {
	position: relative;
	width: 100%;
	padding: var(--pad-row);
	border-radius: var(--radius-card);
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
}

/* Line 1: member (left) + total (right). */
.intervalTile__mainRow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-stack);
}

.intervalTile__memberGroup {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
	min-width: 0;
}

.intervalTile__total {
	font-weight: 600;
	white-space: nowrap;
}

/* Line 2: the muted date/time range, indented under the member name. */
.intervalTile__range {
	opacity: 0.7;
	padding-left: 2.5rem; /* intentional literal: avatar-aligned indent matched to the member row above, not a density step */
}

.intervalTile__teamMember {}

.intervalTile__editButton {
	cursor: pointer;
	position: absolute;
	top: 0;
	right: 0;
	transform: translate(50%, -50%);
}

.intervalTile__deleteButton {
	cursor: pointer;
	position: absolute;
	top: 0;
	right: 0;
	transform: translate(-50%, -50%);
}

/* Hover-reveal is a hover-capable-only affordance (#1641): only devices that
   CAN hover hide the edit/delete buttons behind it — touch devices see them always. */
@media (hover: hover) {

	.intervalTile__editButton,
	.intervalTile__deleteButton {
		opacity: 0;
	}

	.intervalTile__view:hover .intervalTile__editButton {
		opacity: 1;
	}

	.intervalTile__view:hover .intervalTile__deleteButton {
		opacity: 1;
	}
}

/**
* projectDiagrams.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-May-31 Initial Version
*/


.projectDiagrams__view {
	display: grid;
	min-height: 0;
	height: 100%;
	width: 100%;
}

.projectDiagrams__diagram {
	min-height: 0;
}

/**
* taskDiagrams.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-June-10 Initial Version
*/


.taskDiagrams__view {
	display: grid;
	min-height: 0;
	height: 100%;
	width: 100%;
}

.taskDiagrams__diagram {
	min-height: 0;
}

/**
* projectPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-April-07 Initial Version
* @version 2026-July-02 List-tab loading skeleton stack (Tasks / Team Members loading arm)
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

/* First-load stand-in for the list-shaped tabs (Tasks / Team Members). */
.projectPanel__listSkeleton {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
}

.projectPanel__view {
	display: grid;
	gap: var(--gap-stack);
	grid-template-rows: auto auto auto minmax(0, 1fr);
	grid-template-columns: minmax(0, 1fr);
	height: 100%;
	width: 100%;
}

/* TODO: dead rule — no emitter for this selector; its literal is deliberately NOT tokenized. */
.projectPanel__actionButtonsContainer {
	grid-area: projectPanel_actionButtonsContainer;
	display: flex;
	justify-content: flex-end;
	gap: 1rem;
}

.projectPanel__sectionTabs {
	/* justify-self: start; */
}

.projectPanel__diagrams,
.projectPanel__taskTiles,
.projectPanel__teamMembers {
	min-height: 0;
}

.projectPanel__dataContainer {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	min-height: 0;
}

.projectPanel__dataContainer__statRow {
	display: flex;
	gap: var(--gap-stack);
	align-items: stretch;
}

.projectPanel__dataContainer__child {
	flex: 1 1 0;
	min-width: 0;
}

.projectPanel__dataContainer__contentGrid {
	display: grid;
	grid-template-areas:
		'projectPanel_description projectPanel_description'
		'projectPanel_activeTasks projectPanel_workingNow';
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	grid-template-rows: auto 1fr;
	min-height: 0;
}

.projectPanel__dataContainer__description {
	grid-area: projectPanel_description;
}

.projectPanel__dataContainer__activeTasks {
	grid-area: projectPanel_activeTasks;
}

.projectPanel__dataContainer__workingNow {
	grid-area: projectPanel_workingNow;
}

/**
* taskPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-Jun-08 Initial Version
* @version 2026-June-10 Graduate to the ProjectPanel layout: section slider, widget row, slots container
* @version 2026-June-30 Five-tab TabHeaderBar: stat-row/wide-row Details grid (mirrors projectPanel.css);
*          drop the flat slots grid + inline team-member row (Team Members is now its own tab/component)
* @version 2026-June-30 Six-tab (Activity); 5-card statRow (Accuracy) + 2-col content grid below it
* @version 2026-July-02 List-tab loading skeleton stack (Subtasks / Team Members loading arm)
* @version 2026-July-02 Seventh Time tab section cell (min-height so the inner scroll areas can shrink)
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
* @version 2026-July-29 Phone-band statRow collapse (summary cards were clipping at ~390px)
*/

/* First-load stand-in for the list-shaped tabs (Subtasks / Team Members). */
.taskPanel__listSkeleton {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
}

.taskPanel__view {
	display: grid;
	grid-template-rows: auto auto minmax(0, 1fr);
	grid-template-columns: minmax(0, 1fr);
	gap: var(--gap-stack);
	height: 100%;
	width: 100%;
	align-content: start;
}

.taskPanel__dataContainer {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	width: 100%;
	min-height: 0;
}

.taskPanel__dataContainer__statRow {
	display: flex;
	gap: var(--gap-stack);
	width: 100%;
}

.taskPanel__dataContainer__contentGrid {
	display: grid;
	grid-template-areas:
		'taskPanel_dataContainer_description taskPanel_dataContainer_description'
		'taskPanel_dataContainer_statusTimeline taskPanel_dataContainer_assigneeLoad';
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	grid-template-rows: 1fr auto;
	/* gap: 1rem; */
	min-height: 0;
	/* padding: 1rem; */
}

.taskPanel__dataContainer__deadline {
	flex: 1 1 0;
	min-width: 0;
}

.taskPanel__dataContainer__progress {
	flex: 1 1 0;
	min-width: 0;
}

.taskPanel__dataContainer__time {
	flex: 1 1 0;
	min-width: 0;
}

.taskPanel__dataContainer__financial {
	flex: 1 1 0;
	min-width: 0;
}

.taskPanel__dataContainer__description {
	grid-area: taskPanel_dataContainer_description;
}

.taskPanel__dataContainer__statusTimeline {
	grid-area: taskPanel_dataContainer_statusTimeline;
	min-height: 0;
}

.taskPanel__dataContainer__assigneeLoad {
	grid-area: taskPanel_dataContainer_assigneeLoad;
	min-height: 0;
}

/* The Time tab body — let the TaskTime scroll areas shrink inside the panel grid row. */
.taskPanel__timeSection {
	min-height: 0;
}

/* Collapse the four summary cards (deadline/progress/time/financial) to a
   single column in the phone band — at ~390px the flex row squeezed each
   card into ~90px, clipping labels and tabular figures. Same data-viewport
   collapse pattern as newTaskPanel.css (decision 0004: never a viewport
   media query). */
:root[data-viewport="phone"] .taskPanel__dataContainer__statRow {
	flex-direction: column;
}

/**
* taskManagementProfile.css
* @author Louis O. Flores <louis.flores@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-20 Initial Version
* @version 2026-July-29 Shell spacing collapsed onto the app.css role tokens; the
*   doubled page gutter (__view padding + __contentContainer padding) is now the
*   single --pad-page gutter on __contentContainer
*/

.taskManagementProfile__view {
	display: grid;
	gap: var(--gap-inline);
	height: 100%;
	border-radius: var(--radius-button);
}

.taskManagementProfile__mainPanel {
	width: 100%;
	height: 100%;
	background-color: var(--surface-card);
	padding: var(--pad-page);
}

/**
* settingsPanel.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-July-28 Initial Version
*/

.settingsPanel__view {
	display: grid;
	gap: var(--gap-inline);
	height: 100%;
}

.settingsPanel__contentContainer {
	display: grid;
	grid-template-rows: minmax(0, 1fr);
	gap: var(--gap-section);
	overflow: hidden;
	background-color: var(--surface-card);
	border-radius: var(--radius-button);
	padding: var(--pad-page);
	position: relative;
}

.settingsPanel__contentContainer-sideBySide {
	grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}

.settingsPanel__leftPanel {
	height: 100%;
	width: 100%;
	grid-column: 1 / 2;
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
	align-items: start;
}

.settingsPanel__rightPanel {
	height: 100%;
	grid-column: 2 / -1;
}

.settingsPanel__tile {
	width: 100%;
}

/**
* paymentsPanel.css
* @author Francisco Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-August-10 Initial Version
* @version 2026-August-20 The 3DS verify prompt (#1920): its raised row above the
*   sections, and the grid template gains a fourth auto row so the trailing 1fr
*   reservation holds whether or not the prompt renders
*/

.paymentsPanel__grid {
	display: grid;
	grid-template-rows: repeat(4, auto) 1fr;
	gap: var(--gap-section);
}

.paymentsPanel__verifyPrompt {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--gap-stack);
	background: var(--surface-raised);
	border: 1px solid var(--border-default);
	border-radius: var(--radius-card);
	padding: var(--pad-card);
	box-shadow: var(--elevation-raised);
}

.paymentsPanel__verifyText {
	flex: 1 1 240px;
}

.paymentsPanel__verifyButton {
	min-height: 44px;
}

.paymentsPanel__notice {
	padding: var(--pad-card);
}

.paymentsPanel__planCard,
.paymentsPanel__section {
	background: var(--surface-raised);
	border: 1px solid var(--border-default);
	border-radius: var(--radius-card);
	padding: var(--pad-card);
	box-shadow: var(--elevation-raised);
}

:root[data-viewport="phone"] .paymentsPanel__view {
	padding: var(--pad-page);
}

/**
* propertyManagementView.css
* @author Miguel A. González <miguel.gonzalez@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2025-October-03 Initial Version
* @version 2026-July-29 Spacing literals collapsed onto the app.css role tokens
*/

.propertyManagementView__view {
	height: 100%;
	width: 100%;
	display: grid;
	gap: var(--gap-stack);
	grid-template-columns: min-content 0 3fr;
	/* TODO: change when implementing template */
}

.propertyManagementView__mainContainer {}

.propertyManagementView__sidebar {
	display: flex;
	flex-direction: column;
	gap: var(--gap-stack);
}

.propertyManagementView__divider {
	height: 100%;
}
/**
* selfEntityView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-January-31 Initial Version
* @version 2026-July-29 Spacing literal collapsed onto the app.css role tokens
*/

.selfEntityView__view {
	/* background-color: grey; */
	display: grid;
	gap: var(--gap-stack);
	grid-template-rows: auto minmax(0, 1fr);
	height: 100%;
}

.selfEntityView__modulePanel {}

/**
* taskManagementView.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-March-17 Initial Version
*/

.taskManagementView__view {
	height: 100%;
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
	grid-template-columns: minmax(0, 1fr) auto;
	min-height: 0;
}

.taskManagementView__tabHeaderBar {
	grid-column: 1 / 2;
}

.taskManagementView__personalizeButton {
	grid-column: 2 / 2;
	justify-self: end;
	align-self: center;
	color: var(--brand-accent);
}

.taskManagementView__modulePanel {
	height: 100%;
	min-height: 0;
	overflow: hidden;
	grid-column: 1 / -1;
}
/**
* personalizeEntity.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2020-05-15 Initial Version
* @version 2026-May-22 Renamed from personalizeProfile.css
* @version 2026-July-29 Live spacing/type literals collapsed onto the app.css role
*   tokens. The six `var(--Personalize-*)` refs were then DROPPED entirely, keeping only
*   their fallbacks: CustomizeThemePanel now writes bare `--<role>` tokens (it used to
*   write a `--Personalize-`-prefixed name that no stylesheet consumed), so the prefixed
*   lookup was dead in every case and the fallback was always what rendered. Reading the
*   role token directly is the same computed value with one less indirection.
* @version 2026-July-29 Deleted ~400 dead lines (`.personalizeEntity__controllers`
*   through `.personalizeEntity__noTabsMsg`) — confirmed zero emitters in
*   PersonalizeEntity.js since the #1006 read-only theme-picker rewrite (the file
*   now emits only __view + the picker classes retained below).
*/

.personalizeEntity__view {
	height: 100%;
	width: fit-content;
	display: grid;
	gap: var(--gap-inline);
	grid-template-rows: auto 1fr auto;
	padding: var(--pad-shell);
	/* border-radius: var(--radius-button); */
	backdrop-filter: var(--surface-blur);
}

/* Theme picker (#1006) — read-only Style-tab body. */
.personalizeEntity__heading {
	color: var(--text-primary);
	margin: 0 0 var(--gap-stack) 0;
}

.personalizeEntity__pickerList {
	display: flex;
	flex-direction: column;
	gap: var(--gap-inline);
	margin-bottom: var(--gap-tile);
}

.personalizeEntity__pickerRow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-stack);
	padding: var(--pad-button) var(--pad-card);
	cursor: pointer;
	color: var(--text-primary);
	background: var(--surface-card);
	border-radius: var(--radius-button);
	transition: background var(--motion-fast) var(--ease-standard);
}

.personalizeEntity__pickerRow:hover {
	background: var(--surface-hover);
}

.personalizeEntity__pickerRow-active {
	background: var(--surface-selected);
	cursor: default;
}

.personalizeEntity__pickerRowName {
	flex: 1;
	font-weight: 500;
}

.personalizeEntity__pickerRowBadge {
	font-size: var(--font-size-label);
	color: var(--text-secondary);
	text-transform: uppercase;
	letter-spacing: .05em;
}

.personalizeEntity__pickerRowDelete {
	font-size: var(--font-size-label);
	padding: var(--pad-dense);
}

.personalizeEntity__customizeButton {
	justify-self: start;
	width: fit-content;
}

/**
 * utilities.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 * 
 * @version 2019-09-18 Initial Version 
 * @version 2026-August-14 .rumble border reads --status-danger (#1840)
 */

.hide {
	opacity: 0;
}

.exitTop {
	transform: translateY(-100vw);
	opacity: 0;
}

.exitRight {
	transform: translateX(100vw);
	opacity: 0;
}

.exitBottom {
	transform: translateY(100vw);
	opacity: 0;
}

.exitLeft {
	transform: translateX(-100vw);
	opacity: 0;
}

.flatten {
	overflow: hidden;
	padding: 0;
	height: 0;
	border: none;
	margin: 0;
}

.rumble {
	border-color: var(--status-danger);
	animation: shake .5s linear;
}

/* ---- The one sanctioned entrance treatment ----------------------------------
   Compositor-only (opacity + transform), so no layout and no paint. Reduced
   motion is already neutralized app-wide by the `prefers-reduced-motion` block
   in app.css — no local guard. (Deliberately unnumbered: this pointer went stale
   by 14 lines during this PR's own integration when the token layer grew `:root`.)

   `backwards`, never `forwards`/`both`: these elements also carry the global
   `* { transition: all }`, and a filled-forwards animation outranks normal
   declarations, so it would permanently pin `transform` and break every later
   transform write (the panel slide, the drag handler's per-frame writes).
   `backwards` fills only the pre-animation frame and then releases the element.
   For the same reason the `to` state must stay byte-equal to the recipient's own
   base values (`opacity: 1`, no translate) — a mismatch hands off into a visible
   second drift as the live transition chases the base value.

   The recipient selector lives here rather than in floatingExpandablePanel.css so
   the whole treatment is one revertable hunk. It fires with no JS because
   `display: none → grid` on open restarts CSS animations, which is why this one
   selector covers every Dropdown and anchored panel in the app. */
@keyframes motionEnter {
	from {
		opacity: 0;
		transform: translateY(var(--motion-enter-distance));
	}

	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.motion-enter,
.floatingExpandablePanel__view:popover-open,
.floatingExpandablePanel__view[open] {
	animation: motionEnter var(--motion-base) var(--ease-enter) backwards;
}
/**
 * mobileOptimization.css
 * @author Francisco J. Medina <francisco@seedburysquare.com>
 * @copyright Seedbury Square, LLC. All Rights Reserved.
 *
 * @version 2019-09-20 Initial Version
 * @version 2026-July-16 Discrete width-media-query root-size step retired (deleted, not
 *   commented) — superseded by the fluid clamp() root in app.css (#1635)
 * @version 2026-July-17 24px touch-target hard floor under `pointer: coarse` (#1641):
 *   interactive primitives get a real minimum box; absolutely-positioned corner
 *   buttons get the `::after` padded-hit-area instead (growing their box would
 *   shift the translate-anchored visual)
 * @version 2026-August-14 The div-rooted controls join the floor: slider track +
 *   playPause take the padded-hit-area idiom (playPause on `::before` — the cyber
 *   theme owns its `::after`), miniCalendar's visible day cell and the form-control
 *   family take a real minimum box. The form-control family additionally takes the
 *   44px primary floor and the iOS focus-zoom font rung at the phone band — a
 *   cross-cutting rule over three component stylesheets, so it lives here beside its
 *   24px twin rather than being split three ways.
 * @version 2026-August-21 `.legacyShell__appLink` rule deleted — its only emitters were
 *   the three `/inner/` shells, retired with the directory (the `/inner/` cutover)
 */

/* Touch Screen Optimization */

@media (hover: none) {
	.scrollArea {
		overflow: auto;
	}
}

/* The discrete root-size step that used to live here (font-size: 50% under a
   width media query) is superseded by the fluid clamp() root in app.css. */

@media (pointer: coarse) {

	.button,
	.icon__view:where(button):not(.intervalTile__deleteButton, .floatingExpandablePanel__closeButton),
	input[type='checkbox'],
	input[type='radio'] {
		min-width: 24px;
		min-height: 24px;
	}

	/* Slider stops only get the height floor: a min-WIDTH would beat the
	   collapse animation's `max-width: 0` (min-width wins over max-width) and
	   un-collapse every MultiStepSlider. */
	.multiStepSlider__stop {
		min-height: 24px;
	}

	/* Corner buttons anchored with translate(±50%, -50%): growing their box
	   moves the visible glyph, so the tappable area grows via an ::after
	   pseudo-element instead — inset goes negative only while the box is under
	   24px, expanding the hit box without any visual change. (These are the
	   two Icon-root corner buttons excluded from the floor above plus the
	   EditButton corner instances; all are position:absolute at their use
	   sites, which the ::after needs as its containing block.) */
	.compensationView__editButton::after,
	.taskEntryTile__editButton::after,
	.timeLimitTile__editButton::after,
	.deadlineTile__editButton::after,
	.intervalTile__editButton::after,
	.intervalTile__deleteButton::after,
	.floatingExpandablePanel__closeButton::after {
		content: '';
		position: absolute;
		inset: min(0px, calc((100% - 24px) / 2));
	}

	/* Same idiom, two div-rooted controls whose box must not grow: the slider
	   track (its checked-knob translate is hardcoded per size) and playPause
	   (the box IS the clip-path triangle's frame). playPause takes ::before —
	   the cyber theme owns its ::after — and the base rule sets no position, so
	   the containing block comes with it. */
	.slider__sliderContainer::after,
	.playPauseToggleButton__view::before {
		content: '';
		position: absolute;
		inset: min(0px, calc((100% - 24px) / 2));
	}

	.playPauseToggleButton__view {
		position: relative;
	}

	/* The VISIBLE modifier only: `.miniCalendar__day-view` is the hidden state
	   (height/width 0), so a floor on the base class un-hides every empty cell. */
	.miniCalendar__day-view-visible {
		min-width: 24px;
		min-height: 24px;
	}

	/* The form-control family. The focusable element is `.dropdown__headingArea`,
	   not `.dropdown__view` — flooring the shell alone leaves the extra area dead. */
	.textInput__view,
	.dropdown__headingArea,
	.input-smaller,
	.input-small,
	.input-medium,
	.input-large,
	.input-larger,
	textarea {
		min-height: 24px;
	}
}

/* ── 44px primary floor + the iOS focus-zoom font rung (phone band) ──
   The form-control family is the "primary mobile control" tier, and the rule
   spans three component stylesheets, so it lives here beside its 24px twin.
   `--font-size-subheading` measures 16.0px at 320px through 20.0px at 800px, so
   it clears the iOS Safari focus-zoom threshold across the whole band with no
   px literal. */
:root[data-viewport="phone"] .textInput__view,
:root[data-viewport="phone"] .textInput__input,
:root[data-viewport="phone"] .dropdown__headingArea,
:root[data-viewport="phone"] .input-smaller,
:root[data-viewport="phone"] .input-small,
:root[data-viewport="phone"] .input-medium,
:root[data-viewport="phone"] .input-large,
:root[data-viewport="phone"] .input-larger,
:root[data-viewport="phone"] textarea {
	min-height: var(--touch-target-primary);
	font-size: var(--font-size-subheading);
}

/* The `.input-*` rungs set a FIXED height (baseElements.css); it must yield. */
:root[data-viewport="phone"] .input-smaller,
:root[data-viewport="phone"] .input-small,
:root[data-viewport="phone"] .input-medium,
:root[data-viewport="phone"] .input-large,
:root[data-viewport="phone"] .input-larger {
	height: auto;
}

/**
* styleSheet.css
* @author Francisco J. Medina <francisco@seedburysquare.com>
* @copyright Seedbury Square, LLC. All Rights Reserved.
*
* @version 2026-January-31 Set Regions
* @version 2026-July-04 threadSidePanel.css registered; dead messageGroupTile.css import dropped (#1454)
* @version 2026-July-04 requestDetailView.css registered (#1457)
* @version 2026-July-04 itemMessageBoard.css registered (#1455)
* @version 2026-August-10 Payments panel stylesheets registered (cardBrandMark, storageMeter, planStatusCard, paymentMethodList, subscribeConfirmView, addPaymentMethodView, addPayoutAccountView, paymentsPanel)
* @version 2026-August-21 stripeElementsHost.css registered
* @version 2026-August-21 invoicePayOverlay.css + payerChooser.css registered (invoice payer flow)
* @version 2026-August-21 The two `/inner/` imports retired with the directory and menu.css with
*          the dead Menu container (the `/inner/` cutover)
* @version 2026-August-22 receivedInvoiceRow.css registered (#1973/#1979)
*/

/* #region root elements - Must be first  */
/* #endregion */
/* #region Components - should be before containers, but after root elements */
/*  #endregion Components*/
/* #region Containers - should be after components, but before mobile optimization */
/*  #endregion */
/* #region Entity Type Views */
/*  #endregion */
/* #region Utilities */
/*  #endregion */
/* #region Mobile Optimization  - Must be Last */
/* #endregion */

