/* =========================================================================
   PostYard Frontend — full takeover CSS
   ========================================================================= */

:root {
	color-scheme: light dark;

	--py-primary:        #1a56db;
	--py-primary-hover:  #1341a8;
	--py-primary-soft:   #eff4fe;
	--py-success:        #0e7c59;
	--py-success-soft:   #ecfdf5;
	--py-warning:        #b45309;
	--py-warning-soft:   #fef3c7;
	--py-danger:         #c81e1e;
	--py-danger-soft:    #fef2f2;

	--py-ink:            #0f172a;
	--py-ink-muted:      #475569;
	--py-ink-subtle:     #64748b;
	--py-border:         #e2e8f0;
	--py-border-strong:  #cbd5e1;
	--py-surface:        #ffffff;
	--py-surface-alt:    #f8fafc;
	--py-bg:             #f1f5f9;

	--py-radius:         12px;
	--py-radius-sm:      8px;
	--py-radius-lg:      18px;
	--py-shadow-sm:      0 1px 2px rgba(15,23,42,.04), 0 1px 3px rgba(15,23,42,.06);
	--py-shadow:         0 4px 12px rgba(15,23,42,.06), 0 2px 4px rgba(15,23,42,.04);
	--py-shadow-lg:      0 12px 32px rgba(15,23,42,.10), 0 4px 12px rgba(15,23,42,.06);

	--py-sidebar-w:      260px;
	--py-topbar-h:       72px;

	/* Largest the square template canvas may be drawn. Derived from the
	   viewport so the editing surface always fits on screen (the stage sticks
	   below the topbar, and the shortcut legend plus the sticky save bar need
	   room underneath), with a ceiling so it doesn't balloon on a big monitor. */
	--py-canvas-max:     min(620px, calc(100vh - 210px));
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body.py-body {
	margin: 0;
	padding: 0;
	font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
	font-size: 14px;
	line-height: 1.5;
	color: var(--py-ink);
	background: var(--py-bg);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

a { color: var(--py-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

button { font-family: inherit; cursor: pointer; }

/* =========================================================================
   Logo
   ========================================================================= */

.py-logo-mark {
	display: inline-block;
	width: 32px;
	height: 32px;
	background: linear-gradient(135deg, var(--py-primary) 0%, #4f46e5 100%);
	border-radius: 8px;
	position: relative;
	flex-shrink: 0;
}
.py-logo-mark::before,
.py-logo-mark::after {
	content: '';
	position: absolute;
	background: #fff;
	border-radius: 1px;
}
.py-logo-mark::before { left: 7px;  top: 9px;  width: 18px; height: 3px; }
.py-logo-mark::after  { left: 7px;  top: 15px; width: 12px; height: 3px; box-shadow: 0 6px 0 #fff; }

.py-logo-mark--lg { width: 48px; height: 48px; border-radius: 12px; }
.py-logo-mark--lg::before { left: 10px; top: 14px; width: 28px; height: 4px; }
.py-logo-mark--lg::after  { left: 10px; top: 23px; width: 18px; height: 4px; box-shadow: 0 9px 0 #fff; }

.py-logo-text {
	font-size: 18px;
	font-weight: 600;
	letter-spacing: -0.4px;
	color: var(--py-ink);
}
.py-logo-text strong {
	color: var(--py-primary);
	font-weight: 800;
}

.py-logo-text--lg { font-size: 28px; }

/* =========================================================================
   App layout
   ========================================================================= */

.py-app {
	display: grid;
	grid-template-columns: var(--py-sidebar-w) 1fr;
	min-height: 100vh;
}

.py-sidebar {
	background: var(--py-surface);
	border-right: 1px solid var(--py-border);
	padding: 24px 16px;
	display: flex;
	flex-direction: column;
	position: sticky;
	top: 0;
	height: 100vh;
}

.py-sidebar__brand a {
	display: flex;
	align-items: center;
	gap: 10px;
	color: var(--py-ink);
	padding: 4px 8px;
	margin-bottom: 32px;
}
.py-sidebar__brand a:hover { text-decoration: none; }

.py-nav {
	display: flex;
	flex-direction: column;
	gap: 4px;
	flex: 1;
}

.py-nav__item {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 10px 12px;
	border-radius: var(--py-radius-sm);
	color: var(--py-ink-muted);
	font-weight: 500;
	font-size: 14px;
	transition: all .15s ease;
}

.py-nav__item svg {
	width: 18px; height: 18px;
	stroke: currentColor;
	stroke-linejoin: round;
	stroke-linecap: round;
}

.py-nav__item:hover {
	background: var(--py-surface-alt);
	color: var(--py-ink);
	text-decoration: none;
}

.py-nav__item.is-active {
	background: var(--py-primary-soft);
	color: var(--py-primary);
	font-weight: 600;
}

.py-nav__badge {
	margin-left: auto;
	background: var(--py-primary);
	color: #fff;
	font-size: 11px;
	font-weight: 700;
	padding: 2px 7px;
	border-radius: 999px;
	min-width: 20px;
	text-align: center;
}

.py-sidebar__user {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 12px;
	margin-top: 16px;
	border-top: 1px solid var(--py-border);
	padding-top: 16px;
}
.py-user-avatar {
	width: 36px; height: 36px;
	background: linear-gradient(135deg, #6366f1, #8b5cf6);
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #fff;
	font-weight: 600;
	font-size: 14px;
}
.py-user-name { font-weight: 600; font-size: 13px; }
.py-user-logout { font-size: 12px; color: var(--py-ink-subtle); }

/* Install-as-app button — revealed by JS when the browser offers install */
.py-install {
	display: flex;
	align-items: center;
	gap: 10px;
	width: 100%;
	margin-top: 8px;
	padding: 10px 12px;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	background: var(--py-surface);
	color: var(--py-primary);
	font-family: inherit;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
	transition: background .15s ease, border-color .15s ease;
}
.py-install:hover {
	background: var(--py-primary-soft);
	border-color: var(--py-primary);
}
.py-install svg {
	width: 16px; height: 16px;
	stroke-linecap: round;
	stroke-linejoin: round;
}
.py-install[hidden] { display: none; }

/* Main column */

.py-main {
	min-width: 0;
}

.py-topbar {
	height: var(--py-topbar-h);
	background: var(--py-surface);
	border-bottom: 1px solid var(--py-border);
	padding: 0 32px;
	display: flex;
	align-items: center;
	position: sticky;
	top: 0;
	z-index: 10;
}

.py-topbar__title {
	margin: 0;
	font-size: 20px;
	font-weight: 700;
	letter-spacing: -0.3px;
}

.py-content {
	padding: 32px;
	max-width: 1400px;
}

/* =========================================================================
   Stats
   ========================================================================= */

.py-stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
	gap: 16px;
	margin-bottom: 32px;
}

.py-stat {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	padding: 20px 22px;
	box-shadow: var(--py-shadow-sm);
}

.py-stat__number {
	display: block;
	font-size: 32px;
	font-weight: 700;
	line-height: 1;
	color: var(--py-primary);
	letter-spacing: -1px;
}

.py-stat--warning .py-stat__number { color: var(--py-warning); }
.py-stat--success .py-stat__number { color: var(--py-success); }
.py-stat--neutral .py-stat__number { color: var(--py-ink-muted); }

.py-stat__label {
	display: block;
	margin-top: 6px;
	font-size: 12px;
	font-weight: 600;
	color: var(--py-ink-subtle);
	text-transform: uppercase;
	letter-spacing: 0.5px;
}

/* =========================================================================
   Section
   ========================================================================= */

.py-section {
	background: transparent;
	margin-bottom: 32px;
}

.py-section__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 16px;
}

.py-section__header h2 {
	margin: 0;
	font-size: 18px;
	font-weight: 700;
	letter-spacing: -0.3px;
}

.py-section__header small {
	color: var(--py-ink-subtle);
	font-size: 13px;
}

.py-section--muted {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	padding: 24px;
	color: var(--py-ink-muted);
}

.py-link {
	color: var(--py-primary);
	font-weight: 500;
	font-size: 13px;
}

/* =========================================================================
   Post cards
   ========================================================================= */

.py-post-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
	gap: 20px;
}

/* List view — one post per row, full-size square image at 1/3 width */
.py-post-list {
	display: flex;
	flex-direction: column;
	gap: 16px;
}
.py-post-list .py-card {
	flex-direction: row;
	align-items: stretch;
}
.py-post-list .py-card__media {
	flex: 0 0 33%;
	width: 33%;
	max-width: 360px;
	min-width: 240px;
	aspect-ratio: 1 / 1;
}
.py-post-list .py-card__body {
	flex: 1;
	padding: 22px 26px;
}
.py-post-list .py-card__caption {
	-webkit-line-clamp: 7;
}
@media (max-width: 720px) {
	.py-post-list .py-card { flex-direction: column; }
	.py-post-list .py-card__media { width: 100%; max-width: none; flex: 0 0 auto; }
}

.py-card {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	box-shadow: var(--py-shadow-sm);
	overflow: hidden;
	display: flex;
	flex-direction: column;
	transition: all .2s ease;
}
.py-card:hover {
	box-shadow: var(--py-shadow);
	transform: translateY(-1px);
}

.py-card__media {
	position: relative;
	aspect-ratio: 1200 / 628;
	background: var(--py-surface-alt);
	overflow: hidden;
}
.py-card__media img {
	width: 100%; height: 100%;
	object-fit: cover;
	display: block;
}

.py-card__placeholder {
	width: 100%; height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	background: linear-gradient(135deg, #dbeafe 0%, #e0e7ff 100%);
	color: var(--py-primary);
	font-weight: 600;
	font-size: 14px;
	text-align: center;
	padding: 24px;
}

/* Text-only post (graphic_mode = none): a deliberate "no graphic" state,
   styled muted/neutral so it doesn't read as a graphic still rendering. */
.py-card__placeholder--text {
	background: repeating-linear-gradient(45deg, var(--py-surface-alt, #f1f5f9) 0 12px, #e9eef5 12px 24px);
	color: var(--py-ink-subtle, #64748b);
	font-weight: 500;
}

.py-card__platform {
	position: absolute;
	top: 12px;
	right: 12px;
	font-size: 11px;
	font-weight: 600;
	padding: 4px 10px;
	border-radius: 999px;
	display: inline-flex;
	align-items: center;
	gap: 5px;
	backdrop-filter: blur(8px);
}

/* §5 — LinkedIn carousel (PDF document or multi-image album). Mirrors
   .py-card__platform's pill styling, opposite corner so both can show at once. */
.py-card__carousel-badge {
	position: absolute;
	top: 12px;
	left: 12px;
	font-size: 11px;
	font-weight: 600;
	padding: 4px 10px;
	border-radius: 999px;
	background: rgba(15, 23, 42, 0.72);
	color: #fff;
	backdrop-filter: blur(8px);
}

/* A reshare of one of our own posts (or of a watched voice's publication).
   Same slot as the carousel/video badges — a reshare is never either — but
   deliberately in the accent colour rather than their neutral dark: this one
   isn't a format label, it's the answer to "why am I looking at a graphic we
   already published?", so it needs to catch the eye at a glance in the queue. */
.py-card__reshare-badge {
	position: absolute;
	top: 12px;
	left: 12px;
	font-size: 11px;
	font-weight: 600;
	padding: 4px 10px;
	border-radius: 999px;
	background: var(--py-primary);
	color: #fff;
	backdrop-filter: blur(8px);
}

/* graphic_mode = video. Same pill styling/position as the carousel badge —
   the two are mutually exclusive per post, so this is just the video label. */
.py-card__video-badge {
	position: absolute;
	top: 12px;
	left: 12px;
	font-size: 11px;
	font-weight: 600;
	padding: 4px 10px;
	border-radius: 999px;
	background: rgba(15, 23, 42, 0.72);
	color: #fff;
	backdrop-filter: blur(8px);
}

.py-card__body {
	padding: 18px;
	display: flex;
	flex-direction: column;
	gap: 10px;
	flex: 1;
}

.py-card__brand {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.5px;
	color: var(--py-primary);
	text-transform: uppercase;
}

.py-card__caption {
	margin: 0;
	font-size: 13px;
	line-height: 1.55;
	color: var(--py-ink);
	display: -webkit-box;
	-webkit-line-clamp: 5;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.py-card__tags {
	margin: 0;
	font-size: 12px;
	color: var(--py-primary);
}

/* Mention preview — a small line summarising how each @Name in the caption
   will post (native ✓ vs link-only). Deliberately muted + tiny to sit under
   the caption/tags without competing with them. */
.py-card__mentions {
	margin: 0;
	font-size: 11px;
	line-height: 1.4;
	color: var(--py-ink-subtle);
}
.py-card__mention--degraded { color: var(--py-warning); }

.py-card__meta {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
	margin-top: auto;
}

.py-card__time,
.py-card__rev {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	font-size: 11px;
	font-weight: 500;
	color: var(--py-ink-subtle);
	background: var(--py-surface-alt);
	padding: 4px 9px;
	border-radius: 999px;
	border: 1px solid var(--py-border);
}

/* The reshare provenance line on a queue card — who this reshares, and why its
   graphic is one we've published before. Sits directly under the post type,
   above the caption, because it changes how the caption itself should be read. */
.py-card__reshare {
	margin: 0;
	font-size: 12px;
	line-height: 1.5;
	color: var(--py-ink-muted);
	background: var(--py-surface-alt);
	border-left: 3px solid var(--py-primary);
	border-radius: var(--py-radius-sm);
	padding: 8px 10px;
}
.py-card__reshare small {
	display: block;
	margin-top: 2px;
	font-size: 11px;
	color: var(--py-ink-subtle);
}

.py-card__rejection {
	background: var(--py-warning-soft);
	border: 1px solid #fcd34d;
	border-radius: var(--py-radius-sm);
	padding: 10px 12px;
	font-size: 12px;
	color: var(--py-warning);
	line-height: 1.5;
}

/* PostYard's explanation when a rejection asked for something a rewrite can't
   reach (branding, layout, a new photo). Deliberately calm rather than alarming
   — nothing has gone wrong, there's just a different place to do it. */
.py-card__blocked {
	background: var(--py-surface-alt);
	border: 1px solid var(--py-border);
	border-left: 3px solid var(--py-primary);
	border-radius: var(--py-radius-sm);
	padding: 10px 12px;
	font-size: 12px;
	color: var(--py-ink);
	line-height: 1.55;
}

.py-card__blocked > strong {
	display: block;
	margin-bottom: 4px;
}

.py-card__blocked p {
	margin: 0;
}

.py-card__blocked a {
	color: var(--py-primary);
	text-decoration: underline;
}

.py-card__actions {
	display: flex;
	gap: 8px;
	margin-top: 4px;
}

.py-card__reject-form {
	border-top: 1px solid var(--py-border);
	margin-top: 8px;
	padding-top: 12px;
}

.py-card__reject-note {
	width: 100%;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	padding: 10px;
	font-family: inherit;
	font-size: 13px;
	resize: vertical;
}
.py-card__reject-note:focus {
	outline: none;
	border-color: var(--py-primary);
	box-shadow: 0 0 0 3px var(--py-primary-soft);
}
.py-card__reject-note--error {
	border-color: var(--py-danger) !important;
	box-shadow: 0 0 0 3px var(--py-danger-soft) !important;
}
.py-card__reject-note--error::placeholder {
	color: var(--py-danger);
}

.py-card__reject-actions {
	margin-top: 8px;
	display: flex;
	gap: 8px;
}

/* Inline schedule chooser — revealed by the Approve button on Pending
   cards, and by the Reschedule / Change-time buttons on Approved and
   Scheduled cards (same chooser markup, same .py-schedule controls). */
.py-card__approve-form {
	border-top: 1px solid var(--py-border);
	margin-top: 8px;
	padding-top: 12px;
}

.py-card__actions--reschedule {
	margin-top: 10px;
}

.py-schedule__heading {
	margin: 0 0 8px;
	font-size: 12px;
	font-weight: 600;
	color: var(--py-ink-muted);
}

.py-schedule__opt {
	display: flex;
	align-items: flex-start;
	gap: 9px;
	margin-bottom: 6px;
	padding: 9px 10px;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	cursor: pointer;
	transition: border-color .12s ease, background .12s ease;
}
.py-schedule__opt:hover { border-color: var(--py-border-strong); }
.py-schedule__opt:has(input:checked) {
	border-color: var(--py-primary);
	background: var(--py-primary-soft);
}
.py-schedule__opt input[type="radio"] {
	margin: 2px 0 0;
	flex-shrink: 0;
}

.py-schedule__label {
	display: flex;
	flex-direction: column;
	gap: 1px;
	font-size: 13px;
	line-height: 1.4;
}
.py-schedule__label strong { font-weight: 600; color: var(--py-ink); }
.py-schedule__label small  { font-size: 11px; color: var(--py-ink-subtle); }

.py-schedule__when {
	width: 100%;
	box-sizing: border-box;
	margin: -2px 0 6px;
	padding: 8px 10px;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	font-family: inherit;
	font-size: 13px;
	color: var(--py-ink);
}
.py-schedule__when:focus {
	outline: none;
	border-color: var(--py-primary);
	box-shadow: 0 0 0 3px var(--py-primary-soft);
}
.py-schedule__when:disabled {
	opacity: .55;
	cursor: not-allowed;
	background: var(--py-surface-alt);
}
.py-schedule__when--error {
	border-color: var(--py-danger);
	box-shadow: 0 0 0 3px var(--py-danger-soft);
}
.py-schedule__error:not([hidden]) {
	display: block;
	margin: -2px 0 8px;
	font-size: 11px;
	font-weight: 500;
	color: var(--py-danger);
}

.py-card__approve-actions {
	display: flex;
	gap: 8px;
	margin-top: 8px;
}

.py-card--loading { opacity: .5; pointer-events: none; }
.py-card--deleting { opacity: .35; transform: scale(.97); transition: all .25s ease; pointer-events: none; }

/* Small trash icon in the top-right of every card. Subtle by default,
   pops red on hover so accidental clicks are unlikely. */
.py-card__delete {
	position: absolute;
	top: 8px;
	left: 8px;
	background: rgba(255,255,255,.92);
	backdrop-filter: blur(4px);
	border: 1px solid var(--py-border);
	color: var(--py-ink-subtle);
	width: 28px;
	height: 28px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	opacity: 0;
	transition: opacity .15s ease, color .15s ease, background .15s ease, border-color .15s ease;
	z-index: 5;
}
.py-card { position: relative; }
.py-card:hover .py-card__delete { opacity: 1; }
.py-card__delete:hover {
	color: var(--py-danger);
	border-color: var(--py-danger);
	background: var(--py-danger-soft);
}
.py-card__delete:focus-visible {
	opacity: 1;
	outline: 2px solid var(--py-primary);
	outline-offset: 2px;
}
.py-card--approved {
	background: var(--py-success-soft);
	border-color: var(--py-success);
}
.py-card--rejected {
	background: var(--py-danger-soft);
	border-color: var(--py-danger);
}

/* Status banner shown instead of approve/reject buttons for non-pending posts */
.py-card__status {
	padding: 12px 14px;
	border-radius: var(--py-radius-sm);
	font-size: 13px;
	font-weight: 600;
	display: flex;
	flex-direction: column;
	gap: 2px;
}
.py-card__status small {
	font-size: 11px;
	font-weight: 500;
	opacity: .8;
}
.py-card__status--approved {
	background: var(--py-success-soft);
	color: var(--py-success);
	border: 1px solid #6ee7b7;
}
.py-card__status--scheduled {
	background: var(--py-primary-soft);
	color: var(--py-primary);
	border: 1px solid #93c5fd;
}
.py-card__status--rejected {
	background: var(--py-warning-soft);
	color: var(--py-warning);
	border: 1px solid #fcd34d;
}

/* =========================================================================
   Platform badges
   ========================================================================= */

.py-platform {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	font-size: 11px;
	font-weight: 600;
	padding: 3px 8px;
	border-radius: 999px;
	color: #fff;
}
.py-platform--linkedin  { background: #0077b5; }
.py-platform--instagram { background: linear-gradient(45deg,#f09433,#e6683c,#dc2743,#cc2366,#bc1888); }
.py-platform--facebook  { background: #1877f2; }
.py-platform--twitter,
.py-platform--x         { background: #000; }

/* =========================================================================
   Buttons
   ========================================================================= */

.py-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	padding: 9px 16px;
	border-radius: var(--py-radius-sm);
	border: 1px solid transparent;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
	transition: all .12s ease;
	font-family: inherit;
	white-space: nowrap;
}
.py-btn:disabled { opacity: .5; cursor: not-allowed; }
/* A <label>-based button (e.g. a hidden file input) has no native :disabled
   state, so JS toggles this class instead while an upload is in flight. */
.py-btn--disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }

.py-btn--primary {
	background: var(--py-primary);
	color: #fff;
	border-color: var(--py-primary);
	flex: 1;
}
.py-btn--primary:hover {
	background: var(--py-primary-hover);
	border-color: var(--py-primary-hover);
	text-decoration: none;
	color: #fff;
}

.py-btn--ghost {
	background: var(--py-surface);
	color: var(--py-ink-muted);
	border-color: var(--py-border);
}
.py-btn--ghost:hover {
	background: var(--py-surface-alt);
	color: var(--py-ink);
	border-color: var(--py-border-strong);
}

.py-btn--danger {
	background: var(--py-danger);
	color: #fff;
	border-color: var(--py-danger);
}
.py-btn--danger:hover { background: #a01515; border-color: #a01515; color: #fff; }

.py-btn--warning {
	background: var(--py-warning);
	color: #fff;
	border-color: var(--py-warning);
}
.py-btn--warning:hover { background: #92400e; border-color: #92400e; color: #fff; }

.py-btn--block { width: 100%; }
.py-btn--sm    { padding: 6px 12px; font-size: 12px; }

/* =========================================================================
   Team table
   ========================================================================= */

.py-team-table {
	width: 100%;
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	overflow: hidden;
	border-collapse: collapse;
	margin-bottom: 16px;
}
.py-team-table thead {
	background: var(--py-surface-alt);
}
.py-team-table th,
.py-team-table td {
	padding: 14px 18px;
	text-align: left;
	font-size: 14px;
	vertical-align: middle;
	border-bottom: 1px solid var(--py-border);
}
.py-team-table th {
	font-size: 11px;
	font-weight: 700;
	color: var(--py-ink-subtle);
	text-transform: uppercase;
	letter-spacing: 0.5px;
}
.py-team-table tr:last-child td { border-bottom: none; }
.py-team-table__actions { text-align: right; }
.py-team-table select {
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	padding: 5px 10px;
	font-size: 13px;
	background: var(--py-surface);
}
.py-inline-form { display: inline-block; margin: 0; }

/* Per-member brand access editor (Team page) */
.py-brand-access {
	font-size: 13px;
}
.py-brand-access > summary {
	cursor: pointer;
	font-weight: 600;
	color: var(--py-primary);
	list-style: none;
	user-select: none;
}
.py-brand-access > summary::-webkit-details-marker { display: none; }
.py-brand-access > summary::before {
	content: '▸';
	display: inline-block;
	margin-right: 5px;
	font-size: 10px;
	transition: transform .15s;
}
.py-brand-access[open] > summary::before { transform: rotate(90deg); }
.py-brand-access__form {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 12px;
	margin-top: 12px;
	max-width: 380px;
}
.py-brand-access__form .py-checkgroup { gap: 8px; }

.py-team-brands--all  { color: var(--py-ink-subtle); }
.py-team-brands--none { color: var(--py-ink-subtle); font-style: italic; }

.py-diag-log {
	list-style: none;
	padding: 0;
	margin: 0;
	max-height: 360px;
	overflow-y: auto;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	background: var(--py-surface);
	font-family: 'SF Mono', Monaco, monospace;
	font-size: 12px;
}
.py-diag-log li {
	padding: 8px 12px;
	border-bottom: 1px solid var(--py-border);
	display: flex;
	gap: 8px;
	align-items: baseline;
	flex-wrap: wrap;
}
.py-diag-log li:last-child { border-bottom: none; }

/* =========================================================================
   Queue status tabs
   ========================================================================= */

.py-queue-tabs {
	display: flex;
	gap: 4px;
	margin-bottom: 20px;
	border-bottom: 1px solid var(--py-border);
	overflow-x: auto;
}

.py-queue-tab {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 10px 18px;
	font-size: 14px;
	font-weight: 600;
	color: var(--py-ink-subtle);
	border-bottom: 2px solid transparent;
	margin-bottom: -1px;
	transition: all .15s;
	white-space: nowrap;
}
.py-queue-tab:hover {
	color: var(--py-ink);
	text-decoration: none;
}
.py-queue-tab.is-active {
	color: var(--py-primary);
	border-bottom-color: var(--py-primary);
}
.py-queue-tab__count {
	background: var(--py-surface-alt);
	color: var(--py-ink-muted);
	font-size: 11px;
	font-weight: 700;
	padding: 2px 8px;
	border-radius: 999px;
	min-width: 22px;
	text-align: center;
}
.py-queue-tab.is-active .py-queue-tab__count {
	background: var(--py-primary);
	color: #fff;
}

/* =========================================================================
   Filters
   ========================================================================= */

.py-filters {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	margin-bottom: 24px;
}

.py-filters__label {
	font-size: 13px;
	color: var(--py-ink-subtle);
	font-weight: 500;
	margin-right: 4px;
}

.py-chip {
	padding: 5px 14px;
	font-size: 13px;
	border-radius: 999px;
	border: 1px solid var(--py-border);
	color: var(--py-ink-muted);
	background: var(--py-surface);
	font-weight: 500;
	transition: all .15s ease;
}
.py-chip:hover {
	border-color: var(--py-primary);
	color: var(--py-primary);
	text-decoration: none;
}
.py-chip.is-active {
	background: var(--py-primary);
	border-color: var(--py-primary);
	color: #fff;
}
.py-chip.is-active:hover { color: #fff; }

/* =========================================================================
   Bulk action bar — Approve all (queue)
   ========================================================================= */

.py-bulk-bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	box-shadow: var(--py-shadow-sm);
	padding: 14px 18px;
	margin-bottom: 16px;
}

.py-bulk-bar__label {
	font-size: 13px;
	color: var(--py-ink-muted);
}
.py-bulk-bar__label strong {
	color: var(--py-ink);
	font-weight: 700;
}

/* py-btn--primary stretches (flex:1) inside card action rows; in the bulk
   bar the button should hug its own content instead. */
.py-bulk-bar .py-approve-all {
	flex: 0 0 auto;
}

/* =========================================================================
   Pills
   ========================================================================= */

.py-pill {
	display: inline-flex;
	align-items: center;
	font-size: 11px;
	font-weight: 600;
	padding: 3px 9px;
	border-radius: 999px;
	background: var(--py-primary-soft);
	color: var(--py-primary);
}
.py-pill--warning { background: var(--py-warning-soft); color: var(--py-warning); }
.py-pill--success { background: var(--py-success-soft); color: var(--py-success); }
.py-pill--neutral { background: var(--py-surface-alt); color: var(--py-ink-muted); border: 1px solid var(--py-border); }

/* =========================================================================
   Rejected list
   ========================================================================= */

.py-rejected {
	list-style: none;
	padding: 0;
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.py-rejected__item {
	background: var(--py-surface);
	border: 1px solid var(--py-warning-soft);
	border-left: 3px solid var(--py-warning);
	border-radius: var(--py-radius-sm);
	padding: 12px 16px;
	display: grid;
	grid-template-columns: 100px 80px 1fr 200px 60px;
	gap: 12px;
	align-items: center;
	font-size: 13px;
}
.py-rejected__brand   { font-weight: 600; color: var(--py-primary); }
.py-rejected__excerpt { color: var(--py-ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.py-rejected__note    { color: var(--py-warning); font-style: italic; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.py-rejected__rev     { font-size: 11px; color: var(--py-ink-subtle); text-align: right; }

/* =========================================================================
   Empty state
   ========================================================================= */

.py-empty {
	text-align: center;
	padding: 64px 32px;
	background: var(--py-surface);
	border: 2px dashed var(--py-border);
	border-radius: var(--py-radius);
	color: var(--py-ink-muted);
}
.py-empty h2 {
	margin: 0 0 8px;
	font-size: 22px;
	font-weight: 700;
	color: var(--py-ink);
	letter-spacing: -0.3px;
}
.py-empty p {
	margin: 0 0 16px;
	font-size: 14px;
	line-height: 1.6;
	max-width: 500px;
	margin-left: auto;
	margin-right: auto;
}

/* =========================================================================
   Brand grid
   ========================================================================= */

.py-brand-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
	gap: 16px;
}

.py-brand-card {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-top: 4px solid var(--brand-accent, var(--py-primary));
	border-radius: var(--py-radius);
	padding: 20px;
	box-shadow: var(--py-shadow-sm);
}

.py-brand-card__head {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-bottom: 16px;
}
.py-brand-card__logo {
	width: 44px; height: 44px;
	border-radius: 8px;
	object-fit: cover;
}
.py-brand-card__initial {
	width: 44px; height: 44px;
	border-radius: 8px;
	background: var(--brand-accent, var(--py-primary));
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	font-weight: 700;
	font-size: 18px;
}
.py-brand-card__name { margin: 0; font-size: 16px; font-weight: 700; }
.py-brand-card__id   { font-size: 11px; color: var(--py-ink-subtle); }

.py-brand-card__meta {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 8px;
	margin-bottom: 16px;
	font-size: 12px;
}
.py-brand-card__meta dt { color: var(--py-ink-subtle); font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; }
.py-brand-card__meta dd { margin: 0; font-weight: 600; }

/* =========================================================================
   Settings form
   ========================================================================= */

.py-settings-form .py-section {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	padding: 24px;
	margin-bottom: 16px;
}

.py-field {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.py-field__label {
	font-size: 13px;
	font-weight: 600;
	color: var(--py-ink);
}

.py-field input,
.py-field textarea,
.py-field select {
	padding: 10px 14px;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	font-family: inherit;
	font-size: 14px;
	color: var(--py-ink);
	background: var(--py-surface);
	transition: all .15s;
}
.py-field input:focus,
.py-field textarea:focus,
.py-field select:focus {
	outline: none;
	border-color: var(--py-primary);
	box-shadow: 0 0 0 3px var(--py-primary-soft);
}

.py-field__row {
	display: flex;
	gap: 8px;
	align-items: center;
}
.py-field__row input { flex: 1; }

.py-field__hint {
	font-size: 12px;
	color: var(--py-ink-subtle);
	line-height: 1.5;
}
.py-field__hint code {
	background: var(--py-surface-alt);
	padding: 2px 6px;
	border-radius: 4px;
	font-size: 11px;
}

.py-field--checkbox {
	flex-direction: row;
	align-items: center;
	gap: 8px;
}
.py-field--checkbox input { width: auto; }

.py-form-actions {
	display: flex;
	justify-content: flex-end;
	gap: 8px;
	margin-top: 16px;
}

/* =========================================================================
   Toast
   ========================================================================= */

.py-toast {
	padding: 12px 16px;
	border-radius: var(--py-radius-sm);
	margin-bottom: 16px;
	font-size: 13px;
	font-weight: 500;
}
.py-toast--success {
	background: var(--py-success-soft);
	color: var(--py-success);
	border: 1px solid #6ee7b7;
}
.py-toast--error {
	background: var(--py-danger-soft);
	color: var(--py-danger);
	border: 1px solid #fca5a5;
}
.py-toast--info {
	background: var(--py-primary-soft);
	color: var(--py-primary);
	border: 1px solid #93c5fd;
}

/* =========================================================================
   Form grid
   ========================================================================= */

.py-form-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: 16px;
	margin-bottom: 16px;
}

.py-checkgroup {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}

.py-check {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 8px 14px;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	background: var(--py-surface);
	font-size: 13px;
	font-weight: 500;
	cursor: pointer;
	transition: all .15s;
}
.py-check:has(input:checked) {
	background: var(--py-primary-soft);
	border-color: var(--py-primary);
	color: var(--py-primary);
}
.py-check input { width: auto; }

/* File uploader (logo) */

.py-bg-uploader {
	display: grid;
	grid-template-columns: 160px 1fr;
	gap: 20px;
	align-items: start;
}

.py-logo-preview {
	aspect-ratio: 1 / 1;
	border: 2px dashed var(--py-border-strong);
	border-radius: var(--py-radius-sm);
	background: var(--py-surface-alt);
	overflow: hidden;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 16px;
}
.py-logo-preview img {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}
.py-bg-uploader__placeholder {
	text-align: center;
	color: var(--py-ink-subtle);
}
.py-bg-uploader__placeholder svg { color: var(--py-border-strong); margin-bottom: 8px; }
.py-bg-uploader__placeholder p { margin: 0; font-size: 11px; }

.py-bg-uploader__controls {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding-top: 4px;
}

/* Colour picker row */

.py-colour-row {
	display: flex;
	gap: 8px;
	align-items: center;
}
.py-colour-row input[type="color"] {
	width: 56px;
	height: 44px;
	padding: 2px;
	cursor: pointer;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	background: var(--py-surface);
}
.py-colour-row input[type="text"] {
	flex: 1;
	font-family: 'SF Mono', Monaco, monospace;
	font-size: 13px;
	text-transform: uppercase;
}

.py-font-select {
	font-size: 14px;
}
.py-font-select option { font-size: 14px; padding: 4px; }

.py-preview-large-wrap {
	max-width: 520px;
	margin: 0 auto;
	text-align: center;
}
.py-preview-large-wrap .py-canvas {
	border-radius: var(--py-radius);
	box-shadow: var(--py-shadow);
}

/* =========================================================================
   Template strip — one card per template, showing its real colours so a
   six-template post type is scannable rather than a row of identical labels.
   ========================================================================= */

.py-tpl-strip {
	display: flex;
	gap: 10px;
	overflow-x: auto;
	padding: 4px 4px 14px;
	margin-bottom: 4px;
	border-bottom: 1px solid var(--py-border);
	scrollbar-width: thin;
}

.py-tplcard {
	flex: 0 0 auto;
	width: 116px;
	display: flex;
	flex-direction: column;
	gap: 7px;
	padding: 7px;
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	cursor: pointer;
	text-align: left;
	transition: border-color .15s, box-shadow .15s, transform .12s;
}
.py-tplcard:hover { border-color: var(--py-border-strong); transform: translateY(-1px); }
.py-tplcard.is-active {
	border-color: var(--py-primary);
	box-shadow: 0 0 0 3px var(--py-primary-soft);
}

.py-tplcard__thumb {
	position: relative;
	display: block;
	aspect-ratio: 1 / 1;
	border-radius: 5px;
	overflow: hidden;
	background-color: #0f1729;
}
/* Stand-in marks so the thumbnail reads as a layout, not just a swatch. */
.py-tplcard__bar {
	position: absolute;
	left: 12%; top: 16%;
	width: 58%; height: 9%;
	border-radius: 2px;
	opacity: .95;
}
.py-tplcard__bar::after {
	content: '';
	position: absolute;
	left: 0; top: 145%;
	width: 62%; height: 100%;
	border-radius: 2px;
	background: rgba(255,255,255,.55);
}
.py-tplcard__chip {
	position: absolute;
	right: 11%; bottom: 12%;
	width: 24%; height: 11%;
	border-radius: 2px;
	background: rgba(255,255,255,.75);
}

.py-tplcard__meta { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.py-tplcard__name {
	font-size: 12px;
	font-weight: 600;
	color: var(--py-ink);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.py-tplcard__kind { font-size: 10.5px; color: var(--py-ink-subtle); }

.py-tplcard--add {
	justify-content: center;
	gap: 6px;
	width: 148px;
	border-style: dashed;
	background: var(--py-surface-alt);
	cursor: default;
}
.py-tplcard--add:hover { transform: none; }
.py-tplcard--add .py-btn { width: 100%; justify-content: center; }

/* =========================================================================
   Editor: canvas stage + inspector
   ========================================================================= */

.py-tpl-editor {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 330px;
	gap: 20px;
	margin-top: 16px;
	align-items: start;
}

.py-tpl-editor__stage {
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	position: sticky;
	top: calc(var(--py-topbar-h) + 12px);
}

/* The canvas is square, so capping its WIDTH caps its height — that's what
   keeps the whole editing surface on screen. Left to fill the column it grew
   to the full width of a wide display (800px+ tall), pushing the shortcut
   legend and half the inspector below the fold. `--py-canvas-max` is derived
   from the viewport so it also fits a short laptop screen, with an absolute
   ceiling so it never becomes absurd on a large monitor. */
.py-tpl-editor__canvas {
	width: 100%;
	max-width: var(--py-canvas-max);
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	padding: 0;
	overflow: hidden;
}

/* The shortcut legend under the canvas — discoverability for the keyboard
   nudge, which is otherwise invisible. */
.py-tpl-editor__keys {
	width: 100%;
	max-width: var(--py-canvas-max);
	margin: 10px 2px 0;
	font-size: 11.5px;
	color: var(--py-ink-subtle);
	line-height: 1.9;
}
.py-tpl-editor__keys kbd {
	font-family: 'SF Mono', Monaco, monospace;
	font-size: 10.5px;
	padding: 2px 5px;
	border: 1px solid var(--py-border-strong);
	border-bottom-width: 2px;
	border-radius: 4px;
	background: var(--py-surface);
	color: var(--py-ink-muted);
}

/* ---- Inspector ---- */
/* Full remaining viewport height. It was ~100px shorter, which left the
   extra-text editor popover with nowhere to go — its Save/Cancel/Delete row
   fell off the bottom of the panel. */
.py-inspector {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	padding: 14px;
	align-self: start;
	position: sticky;
	top: calc(var(--py-topbar-h) + 12px);
	max-height: calc(100vh - var(--py-topbar-h) - 28px);
	overflow-y: auto;
	overscroll-behavior: contain;
}

.py-inspector__seg {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 2px;
	padding: 2px;
	margin-bottom: 14px;
	background: var(--py-surface-alt);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
}
.py-seg {
	padding: 7px 4px;
	font-size: 12px;
	font-weight: 600;
	color: var(--py-ink-muted);
	background: transparent;
	border: none;
	border-radius: 6px;
	cursor: pointer;
	transition: background .12s, color .12s;
}
.py-seg:hover { color: var(--py-ink); }
.py-seg.is-active {
	background: var(--py-surface);
	color: var(--py-primary);
	box-shadow: var(--py-shadow-sm);
}

.py-inspector__pane { display: none; }
.py-inspector__pane.is-active { display: block; }

.py-inspector__lead {
	margin: 0 0 12px;
	font-size: 12.5px;
	line-height: 1.5;
	color: var(--py-ink-subtle);
}
.py-inspector__selected {
	margin-bottom: 12px;
	padding: 8px 10px;
	font-size: 12.5px;
	color: var(--py-ink-muted);
	background: var(--py-primary-soft);
	border-radius: var(--py-radius-sm);
}
.py-inspector__selected strong { color: var(--py-primary); }

.py-inspector__foot {
	display: flex;
	gap: 6px;
	justify-content: space-between;
	margin-top: 16px;
	padding-top: 14px;
	border-top: 1px solid var(--py-border);
}

/* ---- Layers list ---- */
/* position:relative so the extra-text editor popover can anchor to a row and
   scroll with the inspector rather than floating free of it. */
.py-layers { position: relative; display: flex; flex-direction: column; gap: 2px; }

.py-layer {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 5px 6px;
	border-radius: 6px;
	border: 1px solid transparent;
}
.py-layer:hover { background: var(--py-surface-alt); }
.py-layer.is-selected {
	background: var(--py-primary-soft);
	border-color: var(--py-primary);
}

.py-layer__toggle { display: inline-flex; align-items: center; cursor: pointer; }
.py-layer__toggle input { width: auto; margin: 0; cursor: pointer; }
.py-layer__lock {
	width: 13px;
	text-align: center;
	font-size: 9px;
	color: var(--py-ink-subtle);
	cursor: default;
}

.py-layer__name {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 0;
	padding: 0;
	font-size: 13px;
	font-weight: 600;
	color: var(--py-ink);
	background: none;
	border: none;
	text-align: left;
	cursor: pointer;
}
/* A custom field's hint is its whole AI instruction, which can run long — keep
   the row one line tall and let the popover show the full text. */
.py-layer__name small {
	display: block;
	max-width: 100%;
	font-size: 11px;
	font-weight: 400;
	color: var(--py-ink-subtle);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.py-layer__name:disabled { cursor: default; opacity: .45; }
.py-layer.is-selected .py-layer__name { color: var(--py-primary); }

.py-layers__head {
	margin: 14px 0 4px;
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .5px;
	color: var(--py-ink-subtle);
}
.py-layers__empty {
	margin: 0 0 10px;
	font-size: 12px;
	line-height: 1.5;
	color: var(--py-ink-subtle);
}
.py-layers__add { align-self: flex-start; margin-top: 8px; }

/* Pencil on an extra-text row. Double-click opens the same editor, but a
   double-click is an invisible affordance on its own — this is the visible
   half. Kept faint until the row is hovered or focused so the list stays calm. */
.py-layer__edit {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	padding: 0;
	color: var(--py-ink-subtle);
	background: none;
	border: none;
	border-radius: 5px;
	opacity: 0;
	cursor: pointer;
	transition: opacity .12s, color .12s, background .12s;
}
.py-layer__edit svg { width: 13px; height: 13px; }
.py-layer:hover .py-layer__edit,
.py-layer.is-selected .py-layer__edit,
.py-layer__edit:focus-visible { opacity: 1; }
.py-layer__edit:hover { color: var(--py-primary); background: var(--py-surface); }

/* ---- Extra-text editor popover ---- */
.py-fieldpop {
	position: absolute;
	left: 0;
	right: 0;
	z-index: 30;
	padding: 12px;
	background: var(--py-surface);
	border: 1px solid var(--py-border-strong);
	border-radius: var(--py-radius-sm);
	box-shadow: var(--py-shadow-lg);
}
.py-fieldpop__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	margin-bottom: 10px;
}
.py-fieldpop__head strong { font-size: 12.5px; }
.py-fieldpop__close {
	width: 22px;
	height: 22px;
	padding: 0;
	font-size: 16px;
	line-height: 1;
	color: var(--py-ink-subtle);
	background: none;
	border: none;
	border-radius: 5px;
	cursor: pointer;
}
.py-fieldpop__close:hover { color: var(--py-ink); background: var(--py-surface-alt); }

.py-fieldpop .py-field { margin-bottom: 10px; }
.py-fieldpop textarea { resize: vertical; }

.py-fieldpop__foot {
	display: flex;
	align-items: center;
	gap: 6px;
	padding-top: 10px;
	border-top: 1px solid var(--py-border);
}
.py-fieldpop__spacer { flex: 1; }

.py-canvas--interactive .py-canvas__el.is-selected {
	outline: 2px solid var(--py-primary);
	box-shadow: 0 0 0 4px rgba(26, 86, 219, .25);
}

.py-align-buttons {
	display: flex;
	gap: 4px;
	margin-top: 6px;
}
.py-align-buttons button {
	flex: 1;
	padding: 8px 10px;
	font-size: 12px;
	font-weight: 500;
	background: var(--py-surface-alt);
	color: var(--py-ink-muted);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	cursor: pointer;
}
.py-align-buttons button.is-active {
	background: var(--py-primary);
	color: #fff;
	border-color: var(--py-primary);
}

input[type="range"] {
	width: 100%;
	accent-color: var(--py-primary);
}

@media (max-width: 1020px) {
	.py-tpl-editor { grid-template-columns: 1fr; }
	.py-inspector  { position: static; max-height: none; }
}

/* =========================================================================
   Canva-grade editor: smart guides, resize handles, align toolbar,
   image backgrounds
   ========================================================================= */

/* Smart-guide layer — alignment lines drawn live while dragging. */
.py-canvas__guides {
	position: absolute;
	inset: 0;
	z-index: 5;
	pointer-events: none;
	overflow: hidden;
}
.py-guide { position: absolute; }
.py-guide--v { top: 0;  height: 100%; width: 2px;  transform: translateX(-50%); }
.py-guide--h { left: 0; width: 100%;  height: 2px; transform: translateY(-50%); }
.py-guide--centre { background: #ff2d78; box-shadow: 0 0 6px rgba(255,45,120,.6); }  /* canvas centre */
.py-guide--elem   { background: #13c4d4; box-shadow: 0 0 6px rgba(19,196,212,.5); }  /* aligns to another element */
.py-guide--edge   { background: rgba(255,255,255,.7); }                               /* canvas edge */
/* Grid snap — a quiet 1px line so 5% snapping reads on any background. */
.py-guide--grid.py-guide--v { width: 1px; }
.py-guide--grid.py-guide--h { height: 1px; }
.py-guide--grid { background: rgba(255,255,255,.4); }

/* Resize handles — children of .py-canvas, centred on their anchor point. */
.py-handle {
	position: absolute;
	width: 13px;
	height: 13px;
	background: #fff;
	border: 1.5px solid var(--py-primary);
	border-radius: 3px;
	box-shadow: 0 1px 4px rgba(0,0,0,.45);
	transform: translate(-50%, -50%);
	z-index: 6;
	touch-action: none;
	transition: background .1s ease;
}
.py-handle:hover     { background: var(--py-primary); }
.py-handle.is-active { background: var(--py-primary); box-shadow: 0 0 0 4px rgba(26,86,219,.25), 0 1px 4px rgba(0,0,0,.45); }
.py-handle--nw, .py-handle--se { cursor: nwse-resize; }
.py-handle--ne, .py-handle--sw { cursor: nesw-resize; }
.py-handle--n,  .py-handle--s  { cursor: ns-resize; }
.py-handle--e,  .py-handle--w  { cursor: ew-resize; }
/* The text-box width/height grips read as pills rather than corner squares —
   a pill lying along the edge it resizes, so "this one stretches the box" is
   distinguishable at a glance from the corner squares that scale the type. */
.py-handle--e, .py-handle--w { width: 9px; height: 22px; border-radius: 5px; }
.py-handle--n, .py-handle--s { width: 22px; height: 9px; border-radius: 5px; }

/* Uploaded font library — each row previews the face in itself, which is the
   fastest way to confirm the right file landed. */
.py-fontlib {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin-bottom: 10px;
}
.py-fontlib__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 8px 10px;
	border: 1px solid var(--py-border);
	border-radius: 8px;
	background: var(--py-surface);
}
.py-fontlib__sample {
	font-size: 18px;
	line-height: 1.2;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.py-fontlib__empty {
	margin: 0;
	font-size: 13px;
	color: var(--py-ink-subtle);
}

/* An inline text button that reads as a link — used for "Back to auto" inside
   a hint paragraph, where a full button would shout over the sentence. */
.py-linkbtn {
	background: none;
	border: 0;
	padding: 0;
	font: inherit;
	color: var(--py-primary);
	text-decoration: underline;
	cursor: pointer;
}
.py-linkbtn:hover { text-decoration: none; }

/* Align-on-canvas toolbar — 6 buttons in a 3-column grid. */
#py-elem-pos-row { margin-bottom: 14px; }
#py-elem-w-row   { margin-bottom: 4px; }
.py-pos-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 4px;
	margin-top: 6px;
}
.py-pos-grid button {
	padding: 7px 6px;
	font-size: 12px;
	font-weight: 500;
	background: var(--py-surface-alt);
	color: var(--py-ink-muted);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	cursor: pointer;
	transition: background .12s, color .12s, border-color .12s;
}
.py-pos-grid button:hover {
	color: var(--py-ink);
	border-color: var(--py-primary);
}
.py-pos-grid button.is-flash {
	background: var(--py-primary);
	color: #fff;
	border-color: var(--py-primary);
}

/* Background-image control in the template panel. */
.py-bg-image-control {
	display: flex;
	gap: 12px;
	align-items: flex-start;
	margin-top: 4px;
}
.py-bg-thumb {
	width: 66px;
	height: 66px;
	flex-shrink: 0;
	border-radius: var(--py-radius-sm);
	border: 1px solid var(--py-border);
	background-color: var(--py-surface-alt);
	background-size: cover;
	background-position: center;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}
.py-bg-thumb__empty {
	font-size: 9px;
	font-weight: 600;
	letter-spacing: .04em;
	color: var(--py-ink-subtle);
	text-transform: uppercase;
	text-align: center;
	padding: 0 4px;
}
.py-bg-thumb.has-image .py-bg-thumb__empty { display: none; }
.py-bg-image-control__btns {
	display: flex;
	flex-direction: column;
	gap: 6px;
	flex: 1;
	min-width: 0;
}
.py-bg-image-control__btns .py-btn { width: 100%; }
#py-tpl-bg-remove   { color: var(--py-danger); }
#py-tpl-overlay-block { margin-top: 14px; }
#py-tpl-overlay-mode  { width: 100%; }

/* =========================================================================
   Legacy template-card rules (kept for graceful fallback during deploy)
   ========================================================================= */

.py-templates {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: 16px;
	margin-bottom: 16px;
}

.py-template-card {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	overflow: hidden;
	box-shadow: var(--py-shadow-sm);
}

.py-template-card__preview-wrap {
	/* Wrapper around .py-canvas inside the template card */
}

.py-template-card__controls {
	padding: 14px;
	display: flex;
	flex-direction: column;
	gap: 10px;
	border-top: 1px solid var(--py-border);
}

.py-field--compact .py-field__label { font-size: 11px; }
.py-field--compact input,
.py-field--compact select {
	padding: 6px 10px;
	font-size: 13px;
}
.py-field--compact .py-colour-row input[type="color"] {
	width: 44px; height: 34px;
}

.py-tpl-remove {
	margin-top: 4px;
	color: var(--py-danger) !important;
	border-color: transparent !important;
}
.py-tpl-remove:hover {
	background: var(--py-danger-soft) !important;
	border-color: var(--py-danger) !important;
}
.py-tpl-remove:disabled {
	opacity: .35;
	cursor: not-allowed;
}

/* =========================================================================
   Brand card — uses py-preview-tile inside
   ========================================================================= */

.py-brand-card__preview-link {
	display: block;
	color: inherit;
	margin: -20px -20px 16px;
	position: relative;
	overflow: hidden;
}
.py-brand-card__preview-link:hover { text-decoration: none; }
.py-brand-card__preview-link .py-canvas {
	transition: transform .25s ease;
}
.py-brand-card__preview-link:hover .py-canvas {
	transform: scale(1.02);
}

.py-brand-card__variants {
	position: absolute;
	bottom: 10px;
	left: 10px;
	display: flex;
	gap: 4px;
	background: rgba(0,0,0,.4);
	backdrop-filter: blur(6px);
	border-radius: 999px;
	padding: 4px 8px;
	z-index: 3;
}
.py-variant-dot {
	width: 14px; height: 14px;
	border-radius: 50%;
	border: 2px solid;
	display: inline-block;
}
.py-variant-more {
	font-size: 10px;
	color: #fff;
	font-weight: 700;
	padding-left: 2px;
}

.py-brand-card__body { padding: 0 4px; }


@media (max-width: 700px) {
	.py-bg-uploader { grid-template-columns: 1fr; }
}

/* =========================================================================
   Login
   ========================================================================= */

.py-auth-wrap {
	min-height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	background:
		radial-gradient(circle at 15% 25%, #dbeafe 0%, transparent 50%),
		radial-gradient(circle at 85% 75%, #e0e7ff 0%, transparent 50%),
		var(--py-bg);
	padding: 24px;
}

.py-login__card {
	background: var(--py-surface);
	border-radius: var(--py-radius-lg);
	box-shadow: var(--py-shadow-lg);
	padding: 48px;
	width: 100%;
	max-width: 420px;
}

.py-login__brand {
	text-align: center;
	margin-bottom: 32px;
}
.py-login__brand h1 { margin: 16px 0 4px; }
.py-login__tagline {
	margin: 0;
	color: var(--py-ink-subtle);
	font-size: 13px;
}

.py-login__error {
	background: var(--py-danger-soft);
	border: 1px solid #fca5a5;
	color: var(--py-danger);
	padding: 12px 14px;
	border-radius: var(--py-radius-sm);
	font-size: 13px;
	margin-bottom: 16px;
}

.py-login__form {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.py-login__footer {
	text-align: center;
	margin-top: 24px;
	font-size: 12px;
	color: var(--py-ink-subtle);
}

/* =========================================================================
   Post detail
   ========================================================================= */

.py-back-link {
	display: inline-block;
	color: var(--py-ink-subtle);
	margin-bottom: 20px;
	font-size: 13px;
}

.py-detail {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 32px;
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	padding: 32px;
}

/* The media column is ONE grid child. It used to be three — the graphic, the
   "Edit graphic" row and the "Attach video" row — which a two-column grid
   auto-placed cell by cell, dropping the controls into the right-hand column
   beside the graphic and shunting the copy into the next row. Wrapping them
   makes the left column an actual column, which is most of why this page
   read as scattered. The graphic sticks while the copy scrolls past it, so a
   long caption is read against the thing it describes. */
.py-detail__col {
	align-self: start;
	position: sticky;
	top: 20px;
}
.py-detail__media img,
.py-detail__media video {
	width: 100%;
	border-radius: var(--py-radius-sm);
	display: block;
}

/* -----------------------------------------------------------------------------
   Media toolbar — every manipulation of the graphic above it, in one strip.

   "Edit graphic" and "Attach video" were two separate rows, each trailing its
   own sentence of hint text, so the space under the media read as a pile of
   loose controls. They are one bordered strip now: buttons on a row, the hints
   collapsed to a single muted line beneath. Each control is still rendered
   independently by its own gate — the strip only draws when at least one is
   available.
   -------------------------------------------------------------------------- */
.py-detail__tools {
	margin-top: 12px;
	padding: 12px 14px;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	background: var(--py-surface-alt);
}
.py-detail__tools-row {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
}
.py-detail__tools-row .py-btn { flex: 0 0 auto; }
.py-detail__tools-hint {
	margin: 8px 0 0;
	font-size: 12px;
	line-height: 1.5;
	color: var(--py-ink-muted);
}
.py-detail__tools-hint strong { color: var(--py-ink); font-weight: 600; }

/* Attach/replace video — post-detail, pending posts only. The wrapper keeps
   its own element so the upload handler can find its label and status line. */
.py-detail__attach-video {
	display: inline-flex;
	align-items: center;
	gap: 8px;
}
.py-detail__attach-video-status {
	font-size: 12px;
	font-weight: 600;
	color: var(--py-primary);
}
.py-detail__attach-video-status:empty { display: none; }

.py-detail__meta {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
	margin-bottom: 16px;
}
.py-detail__title {
	margin: 0 0 12px;
	font-size: 24px;
	font-weight: 800;
	letter-spacing: -0.5px;
}
.py-detail__caption {
	font-size: 14px;
	line-height: 1.7;
	color: var(--py-ink);
	white-space: pre-line;
}
.py-detail__tags { color: var(--py-primary); font-weight: 500; }

/* -----------------------------------------------------------------------------
   Body-column sections — links, mentions, HubSpot, WordPress, LinkedIn.

   One rule instead of five inline copies of the same heading style, so the
   blocks stack at a consistent rhythm and are separated by a rule rather than
   by nothing at all. .py-manual-actions is the delivery blocks' existing class
   (it had no styling of its own before) and is folded in here so a post page
   reads the same from top to bottom whatever its delivery mode.
   -------------------------------------------------------------------------- */
.py-detail__section,
.py-manual-actions {
	margin: 20px 0 0;
	padding-top: 20px;
	border-top: 1px solid var(--py-border);
}
.py-detail__section-title {
	margin: 0 0 8px;
	font-size: 12px;
	font-weight: 700;
	color: var(--py-ink-subtle);
	text-transform: uppercase;
	letter-spacing: .5px;
}
.py-detail__section-lede {
	margin: 0 0 12px;
	font-size: 14px;
	line-height: 1.6;
	color: var(--py-ink-muted);
}
.py-detail__note { color: var(--py-ink-muted); }

/* §11 link-check notes. */
.py-detail__link-note {
	margin: 0 0 10px;
	font-size: 13px;
	line-height: 1.6;
}
.py-detail__link-note--last { margin-bottom: 0; }
.py-detail__link-urls {
	color: var(--py-ink-muted);
	word-break: break-all;
}

/* Mention preview list. */
.py-detail__mention-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.py-detail__mention-list li {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	font-size: 13px;
}

/* §5 — LinkedIn carousel album slides (multi-image fallback format). */
.py-detail__carousel-slides {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 4px 0 0;
}
.py-detail__carousel-slides img {
	width: 96px;
	height: 96px;
	object-fit: cover;
	border-radius: 8px;
	border: 1px solid var(--py-border, #e2e8f0);
}
.py-detail__time {
	margin: 16px 0 0;
	font-size: 13px;
	color: var(--py-ink-muted);
}

/* The verdict row. It reads as the end of the page rather than as one more
   paragraph of it — it was butting straight up against whatever section
   happened to render last (mentions, a suggested time, an article's tags). */
.py-detail__body > .py-card__actions {
	margin-top: 20px;
	padding-top: 20px;
	border-top: 1px solid var(--py-border);
}

/* Full WordPress article body rendered on the post-detail page. */
.py-detail__article {
	margin: 16px 0;
	padding: 16px 18px;
	border: 1px solid var(--py-border);
	border-radius: 10px;
	background: var(--py-surface, #fff);
	font-size: 15px;
	line-height: 1.7;
	color: var(--py-ink);
	max-width: 70ch;
}
.py-detail__article > :first-child { margin-top: 0; }
.py-detail__article > :last-child { margin-bottom: 0; }
.py-detail__article h1,
.py-detail__article h2,
.py-detail__article h3,
.py-detail__article h4 { line-height: 1.3; margin: 1.2em 0 0.4em; }
.py-detail__article p { margin: 0 0 1em; }
.py-detail__article ul,
.py-detail__article ol { margin: 0 0 1em; padding-left: 1.4em; }
.py-detail__article li { margin: 0.25em 0; }
.py-detail__article a { color: var(--py-primary); }
.py-detail__article img { max-width: 100%; height: auto; border-radius: 8px; }
.py-detail__article blockquote {
	margin: 0 0 1em;
	padding-left: 14px;
	border-left: 3px solid var(--py-border);
	color: var(--py-ink-muted);
}
.py-detail__article-meta { font-size: 13px; color: var(--py-ink-muted); margin: 4px 0 0; }
.py-detail__revisions {
	margin-top: 24px;
	padding-top: 24px;
	border-top: 1px solid var(--py-border);
}
.py-detail__revisions blockquote {
	margin: 4px 0 0 0;
	padding: 8px 12px;
	background: var(--py-warning-soft);
	border-left: 3px solid var(--py-warning);
	border-radius: 0 var(--py-radius-sm) var(--py-radius-sm) 0;
	font-size: 13px;
	color: var(--py-warning);
}

/* =========================================================================
   Responsive
   ========================================================================= */

@media (max-width: 1024px) {
	.py-detail { grid-template-columns: 1fr; }
	.py-detail__col { position: static; }
}

@media (max-width: 768px) {
	:root { --py-sidebar-w: 0; }
	.py-app { grid-template-columns: 1fr; }
	.py-sidebar {
		position: fixed;
		left: -260px;
		width: 260px;
		z-index: 100;
		transition: left .25s;
	}
	.py-sidebar.is-open { left: 0; }
	.py-content { padding: 20px; }
	.py-topbar { padding: 0 20px; }
	.py-rejected__item { grid-template-columns: 1fr; }
}

/* =========================================================================
   Mobile navigation toggle + overlay
   ========================================================================= */

/* Hamburger button — hidden on desktop, shown on mobile */
.py-topbar__menu-btn {
	display: none;
	background: none;
	border: none;
	padding: 8px;
	margin-right: 8px;
	color: var(--py-ink);
	border-radius: var(--py-radius-sm);
	cursor: pointer;
	flex-shrink: 0;
	align-items: center;
	justify-content: center;
}
.py-topbar__menu-btn svg {
	width: 22px;
	height: 22px;
	display: block;
	stroke-linecap: round;
	stroke-linejoin: round;
}
.py-topbar__menu-btn:hover { background: var(--py-surface-alt); }

/* Dimming overlay behind the open sidebar */
.py-sidebar-overlay {
	display: none;
	position: fixed;
	inset: 0;
	background: rgba(15,23,42,.45);
	z-index: 99;
	backdrop-filter: blur(2px);
	-webkit-backdrop-filter: blur(2px);
}
@keyframes py-fade-in { from { opacity: 0; } to { opacity: 1; } }
.py-sidebar-overlay.is-visible {
	display: block;
	animation: py-fade-in .2s ease;
}

/* Team table — horizontal scroll on mobile so the 5-column layout doesn't overflow */
.py-team-table-wrap {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	border-radius: var(--py-radius);
	margin-bottom: 16px;
}
.py-team-table-wrap .py-team-table {
	margin-bottom: 0;
	min-width: 560px;
}

@media (max-width: 768px) {
	.py-topbar__menu-btn { display: flex; }
}

/* =========================================================================
   Small-screen layout (≤ 600 px)
   ========================================================================= */

/* =========================================================================
   Request queue
   ========================================================================= */

.py-request-form-wrap {
	max-width: 640px;
}

.py-request-form {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

/* NOTE: a byte-identical duplicate of the canonical `.py-field` rule used to
   sit here. Being later in the file, it re-applied `flex-direction: column`
   AFTER `.py-field--checkbox` had set `row` — so every checkbox-with-a-label
   row in the app stacked and centred instead of sitting side by side. Removed
   rather than re-scoped: it added nothing the earlier rule doesn't already do. */

.py-label {
	font-size: 13px;
	font-weight: 600;
	color: var(--py-text-muted);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.py-select {
	width: 100%;
	padding: 9px 12px;
	border: 1px solid var(--py-border);
	border-radius: 8px;
	background: var(--py-surface);
	color: var(--py-text);
	font-size: 14px;
	font-family: inherit;
}

.py-textarea {
	width: 100%;
	padding: 10px 12px;
	border: 1px solid var(--py-border);
	border-radius: 8px;
	background: var(--py-surface);
	color: var(--py-text);
	font-size: 14px;
	font-family: inherit;
	resize: vertical;
	line-height: 1.5;
	box-sizing: border-box;
}

.py-textarea:focus,
.py-select:focus {
	outline: none;
	border-color: var(--py-primary);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--py-primary) 20%, transparent);
}

.py-field__hint {
	font-size: 12px;
	color: var(--py-text-muted);
	margin: 0;
}

.py-request-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.py-request-list--consumed {
	opacity: 0.75;
}

.py-request-item {
	display: flex;
	align-items: flex-start;
	gap: 16px;
	padding: 16px;
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: 10px;
}

.py-request-item--consumed {
	border-style: dashed;
}

.py-request-item__content {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.py-request-item__brand {
	align-self: flex-start;
}

.py-request-item__body {
	margin: 0;
	font-size: 14px;
	line-height: 1.55;
	color: var(--py-text);
}

.py-request-item__meta {
	font-size: 12px;
	color: var(--py-text-muted);
}

.py-request-item__meta code {
	font-size: 11px;
	background: var(--py-bg);
	padding: 1px 5px;
	border-radius: 4px;
}

.py-request-item__status {
	font-size: 13px;
	font-weight: 600;
	color: var(--py-success);
	white-space: nowrap;
	padding-top: 2px;
}

.py-empty--inline {
	padding: 16px 0;
}

/* Campaign timeline — one block per ISO week, posts as compact rows. */
.py-campaign-timeline {
	display: flex;
	flex-direction: column;
	gap: 20px;
}

.py-campaign-week__label {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 13px;
	text-transform: uppercase;
	letter-spacing: .5px;
	color: var(--py-ink-subtle, var(--py-text-muted));
	margin: 0 0 8px;
}

/* =========================================================================
   Mobile — ≤ 600 px
   ========================================================================= */

@media (max-width: 600px) {
	.py-content { padding: 16px; }
	.py-topbar  { padding: 0 16px; }

	/* Single-column grids — avoids minmax overflow on 320 px phones */
	.py-post-grid  { grid-template-columns: 1fr; }
	.py-brand-grid { grid-template-columns: 1fr; }

	/* Filters scroll horizontally rather than wrap to a second row */
	.py-filters {
		flex-wrap: nowrap;
		overflow-x: auto;
		padding-bottom: 4px;
		-webkit-overflow-scrolling: touch;
	}

	/* Login card — reduce heavy 48 px padding */
	.py-login__card { padding: 28px 20px; }

	/* Post detail — reduce heavy 32 px padding */
	.py-detail { padding: 20px; gap: 20px; }

	/* Stats — slightly smaller on tiny screens */
	.py-stat__number { font-size: 26px; }
	.py-stat { padding: 16px 18px; }

	/* Section header — let the subtitle wrap to its own row */
	.py-section__header { flex-wrap: wrap; gap: 8px; }
	.py-section__header small { width: 100%; }

	/* Topbar title — tighten up a touch */
	.py-topbar__title { font-size: 17px; }

	/* Bulk approve bar — stack vertically */
	.py-bulk-bar { flex-direction: column; align-items: stretch; }
	.py-bulk-bar .py-approve-all { width: 100%; justify-content: center; }

	/* Queue tabs — always scroll, never shrink text */
	.py-queue-tabs { padding-bottom: 0; }

	/* Nav items — bump touch target to ≥ 44 px */
	.py-nav__item { padding: 13px 12px; }
}

/* =========================================================================
   Dark theme — follows the OS setting via prefers-color-scheme. Placed last
   in the file on purpose: the UI is entirely variable-driven, so re-pointing
   the tokens re-themes everything, and the two non-variable patches below
   then win the cascade over the light rules they override.
   ========================================================================= */

@media (prefers-color-scheme: dark) {
	:root {
		--py-primary:        #5b8cf0;
		--py-primary-hover:  #7299f2;
		--py-primary-soft:   #1f2c46;
		--py-success:        #34d399;
		--py-success-soft:   #123026;
		--py-warning:        #fbbf47;
		--py-warning-soft:   #382c12;
		--py-danger:         #f87171;
		--py-danger-soft:    #3a1f22;

		--py-ink:            #e6ebf2;
		--py-ink-muted:      #a6b1c2;
		--py-ink-subtle:     #7e8a9d;
		--py-border:         #2a3550;
		--py-border-strong:  #3c4a66;
		--py-surface:        #18202f;
		--py-surface-alt:    #212b3e;
		--py-bg:             #0e1523;

		--py-shadow-sm:      0 1px 2px rgba(0,0,0,.4), 0 1px 3px rgba(0,0,0,.5);
		--py-shadow:         0 4px 12px rgba(0,0,0,.45), 0 2px 4px rgba(0,0,0,.4);
		--py-shadow-lg:      0 12px 32px rgba(0,0,0,.55), 0 4px 12px rgba(0,0,0,.4);
	}

	/* Empty-image card placeholder — a pale-blue gradient otherwise. */
	.py-card__placeholder { background: var(--py-surface-alt); }

	/* Login backdrop — its pale radial glows would blow out on dark. */
	.py-auth-wrap {
		background:
			radial-gradient(circle at 15% 25%, #1d2c4d 0%, transparent 50%),
			radial-gradient(circle at 85% 75%, #241d4d 0%, transparent 50%),
			var(--py-bg);
	}

	/* Solid CTA buttons — the accent tokens above are tuned for legible text
	   on dark, which leaves them too light to carry white button labels.
	   Darker fills here keep the labels at AA contrast. */
	.py-btn--primary       { background: #2f6fe0; border-color: #2f6fe0; }
	.py-btn--primary:hover { background: #3a73e6; border-color: #3a73e6; }
	.py-btn--danger        { background: #c5302f; border-color: #c5302f; }
	.py-btn--danger:hover  { background: #d8423f; border-color: #d8423f; }
}

/* =========================================================================
   Asset Library
   ========================================================================= */

.py-assets-layout {
	display: grid;
	grid-template-columns: 220px 1fr;
	gap: 1.5rem;
	align-items: start;
}

@media (max-width: 768px) {
	.py-assets-layout { grid-template-columns: 1fr; }
}

/* Sidebar */
.py-assets-sidebar {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	padding: .75rem;
}

.py-assets-sidebar__title {
	font-size: .75rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--py-ink-subtle);
	margin: 0 0 .5rem .5rem;
}

.py-folder-link {
	display: flex;
	align-items: center;
	gap: .5rem;
	padding: .5rem .75rem;
	border-radius: var(--py-radius-sm);
	text-decoration: none;
	color: var(--py-ink);
	font-size: .875rem;
	transition: background .15s;
}

.py-folder-link:hover { background: var(--py-surface-alt); }
.py-folder-link.is-active { background: var(--py-primary-soft); color: var(--py-primary); font-weight: 600; }

.py-folder-link__icon {
	display: flex;
	flex-shrink: 0;
	color: var(--py-ink-subtle);
}
.py-folder-link__icon svg { width: 16px; height: 16px; }
.py-folder-link.is-active .py-folder-link__icon { color: var(--py-primary); }

/* Folder name takes the slack; the count stays pinned to the right. */
.py-folder-link__name {
	flex: 1;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	min-width: 0;
}

.py-folder-count {
	font-size: .75rem;
	color: var(--py-ink-subtle);
	min-width: 1.5rem;
	text-align: right;
}

/* Breadcrumb */
.py-breadcrumb {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .35rem;
	font-size: .85rem;
	margin-bottom: 1rem;
}
.py-breadcrumb a { color: var(--py-ink-subtle); text-decoration: none; }
.py-breadcrumb a:hover { color: var(--py-primary); }
.py-breadcrumb__sep { color: var(--py-ink-subtle); }
.py-breadcrumb__current { font-weight: 600; color: var(--py-ink); }

/* Toolbar */
.py-assets-toolbar {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem;
	margin-bottom: 1rem;
}

/* Sub-folder tiles — the Finder-style picker */
.py-folder-tiles {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
	gap: .75rem;
	margin-bottom: 1.5rem;
}
.py-folder-tile {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: .65rem;
	align-items: center;
	padding: .7rem .85rem;
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	text-decoration: none;
	color: var(--py-ink);
	transition: box-shadow .15s, border-color .15s;
}
.py-folder-tile:hover {
	box-shadow: var(--py-shadow);
	border-color: var(--py-border-strong);
}
.py-folder-tile__icon {
	grid-row: 1 / 3;
	display: flex;
	color: var(--py-primary);
}
.py-folder-tile__icon svg { width: 28px; height: 28px; }
.py-folder-tile__name {
	grid-column: 2;
	font-size: .85rem;
	font-weight: 600;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	min-width: 0;
}
.py-folder-tile__meta {
	grid-column: 2;
	font-size: .7rem;
	color: var(--py-ink-subtle);
}

.py-folder-edit-form {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	padding: 1rem;
	margin-bottom: 1rem;
	display: flex;
	flex-direction: column;
	gap: .75rem;
}

/* Upload zone */
.py-upload-zone {
	border: 2px dashed var(--py-border-strong);
	border-radius: var(--py-radius);
	padding: 2rem;
	text-align: center;
	transition: border-color .15s, background .15s;
	margin-bottom: 1.5rem;
}

.py-upload-zone.is-dragover {
	border-color: var(--py-primary);
	background: var(--py-primary-soft);
}

.py-upload-zone__inner p { margin: .5rem 0 0; }

.py-upload-zone__icon {
	width: 32px;
	height: 32px;
	color: var(--py-ink-subtle);
}

.py-upload-zone__progress {
	margin-top: 1rem;
}

.py-upload-zone__bar {
	height: 6px;
	background: var(--py-border);
	border-radius: 3px;
	overflow: hidden;
	margin-bottom: .5rem;
}

.py-upload-zone__fill {
	height: 100%;
	background: var(--py-primary);
	border-radius: 3px;
	width: 0;
	transition: width .3s;
}

/* Asset grid */
.py-asset-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
	gap: 1rem;
}

.py-asset-card {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	overflow: hidden;
	transition: box-shadow .15s;
}

.py-asset-card:hover { box-shadow: var(--py-shadow); }

.py-asset-card__thumb {
	aspect-ratio: 1;
	background: var(--py-surface-alt);
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}

.py-asset-card__thumb img {
	width: 100%;
	height: 100%;
	object-fit: contain;
}

.py-asset-card__info {
	padding: .5rem .625rem;
	display: flex;
	flex-direction: column;
	gap: .125rem;
}

.py-asset-card__title {
	font-size: .8125rem;
	font-weight: 500;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.py-asset-card__meta {
	font-size: .6875rem;
	color: var(--py-ink-subtle);
}

/* Vector-format badge on an SVG asset card. */
.py-asset-tag {
	display: inline-block;
	font-size: .625rem;
	font-weight: 700;
	letter-spacing: .03em;
	padding: .05rem .3rem;
	margin-right: .15rem;
	border-radius: 3px;
	background: var(--py-primary-soft);
	color: var(--py-primary);
	vertical-align: .05rem;
}

.py-asset-card__actions {
	display: flex;
	gap: .25rem;
	padding: 0 .5rem .5rem;
}

/* Asset-card icon buttons: a flattened, borderless take on the ghost button.
   This used to be an UNSCOPED `.py-btn--ghost` redefinition, so — sitting later
   in the file than the canonical rule at the top — it silently stripped the
   border, background and padding off EVERY ghost button in the app (Cancel,
   Duplicate, Replace logo, Find my channels…), leaving them looking like bare
   text links. Scoped to the three asset-card buttons it was written for: the
   asset library looks exactly as it did, and ghost buttons elsewhere get the
   styling they were always meant to have. */
.py-asset-card__actions .py-btn--ghost {
	background: none;
	border: none;
	color: var(--py-ink-subtle);
	cursor: pointer;
	padding: .25rem;
	border-radius: var(--py-radius-sm);
	transition: color .15s, background .15s;
}

.py-asset-card__actions .py-btn--ghost:hover { color: var(--py-ink); background: var(--py-surface-alt); }
.py-asset-card__actions .py-btn--ghost.py-btn--danger:hover { color: var(--py-danger); }

.py-btn--xs { font-size: .75rem; padding: .2rem .35rem; }

.py-link {
	background: none;
	border: none;
	color: var(--py-primary);
	cursor: pointer;
	text-decoration: underline;
	font: inherit;
	padding: 0;
}

/* ─── Visual email editor (brand edit → Auto-send → Email design) ─── */
.py-email-editor { margin-top: 10px; }
.py-email-editor__add { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.py-email-editor__cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; }
@media (max-width: 900px) { .py-email-editor__cols { grid-template-columns: 1fr; } }
.py-email-editor__blocks { display: flex; flex-direction: column; gap: 10px; }
.py-email-editor__preview-label { font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--py-ink-subtle, #64748b); margin-bottom: 6px; }

.py-email-block { border: 1px solid var(--py-border, #e5e7eb); border-radius: 8px; padding: 10px 12px; background: var(--py-surface, #fff); }
.py-email-block__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.py-email-block__tools { display: flex; gap: 4px; }
.py-email-block__tool { width: 26px; height: 26px; border: 1px solid var(--py-border, #e5e7eb); background: var(--py-surface-sunken, #f6f8fa); border-radius: 6px; cursor: pointer; font-size: 12px; line-height: 1; color: var(--py-ink, #0f172a); }
.py-email-block__tool:disabled { opacity: .4; cursor: not-allowed; }
.py-email-block__tool.is-danger { color: var(--py-danger, #c81e1e); }

.py-email-field { display: flex; flex-direction: column; gap: 3px; margin-bottom: 8px; font-size: 12px; color: var(--py-ink-subtle, #64748b); }
.py-email-field span { font-weight: 600; }
.py-email-field input, .py-email-field select, .py-email-field textarea { width: 100%; box-sizing: border-box; padding: 6px 8px; border: 1px solid var(--py-border, #e5e7eb); border-radius: 6px; font: inherit; font-size: 13px; }
.py-email-field input[type="color"] { height: 32px; padding: 2px; }

/* ---------------------------------------------------------------------------
   Weekly calendar (/calendar)

   A day×hour timetable: a left time-axis column plus seven day columns, sharing
   one hour band down the side. Every day×hour cell is a drop target. The grid
   keeps its shape at every width and scrolls sideways inside .py-cal-scroll on
   narrow screens (never the page body). Hairline gridlines are the 1px grid gap
   showing the border colour beneath, so cells stay single-pixel-separated in
   both themes. Status colours reuse the palette variables so the dark theme at
   the foot of this file needs no calendar-specific overrides.
--------------------------------------------------------------------------- */

.py-cal-bar {
	display: flex; align-items: center; justify-content: space-between;
	gap: 16px; flex-wrap: wrap; margin-bottom: 16px;
}
.py-cal-bar__nav { display: flex; gap: 6px; }
.py-cal-bar__range { text-align: right; font-size: 15px; }
.py-cal-bar__meta { display: block; font-size: 12px; color: var(--py-ink-subtle); font-weight: 400; }

.py-cal-windows {
	display: flex; flex-wrap: wrap; gap: 6px 18px;
	margin-bottom: 14px; font-size: 12px; color: var(--py-ink-subtle);
}

/* Horizontal scroll container — the grid keeps its column widths and scrolls
   sideways in here on narrow screens, so the page body never scrolls. */
.py-cal-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.py-cal {
	display: grid;
	grid-template-columns: 56px repeat(7, minmax(84px, 1fr));
	gap: 1px;                               /* hairline gridlines… */
	background: var(--py-border);           /* …the border colour, shown through the gap */
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	overflow: hidden;                       /* clip the cells to the rounded frame */
	min-width: 720px;                       /* forces the sideways scroll when narrow */
}
.py-cal__corner,
.py-cal__dayhead,
.py-cal__axis,
.py-cal__cell { background: var(--py-surface); }

.py-cal__dayhead {
	display: flex; align-items: baseline; justify-content: space-between; gap: 6px;
	padding: 8px 10px;
}
.py-cal__dayhead.is-today { background: var(--py-primary-soft); }
.py-cal__dayhead.is-past  { background: var(--py-surface-alt); }
.py-cal__dayname { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--py-ink-subtle); font-weight: 600; }
.py-cal__daynum  { font-size: 16px; font-weight: 700; color: var(--py-ink); }

/* The time axis down the left edge — one HH:00 label per hour row. */
.py-cal__axis {
	padding: 6px 8px; text-align: right;
	font-size: 11px; font-weight: 600;
	font-variant-numeric: tabular-nums;
	color: var(--py-ink-subtle);
	background: var(--py-surface-alt);
}

.py-cal__cell {
	padding: 5px;
	min-height: 46px;
	display: flex; flex-direction: column; gap: 5px;
}
.py-cal__cell.is-today { background: var(--py-primary-soft); }
.py-cal__cell.is-past  { background: var(--py-surface-alt); }   /* wins over is-today for a past hour today */

.py-cal__post {
	display: flex; flex-direction: column; gap: 2px;
	padding: 7px 8px;
	border-radius: 6px;
	border-left: 3px solid var(--py-border-strong);
	background: var(--py-surface-alt);
	font-size: 12px;
	color: var(--py-ink);
	text-decoration: none;
	transition: transform .12s ease, box-shadow .12s ease;
}
.py-cal__post:hover { transform: translateY(-1px); box-shadow: var(--py-shadow-sm); text-decoration: none; }
.py-cal__time    { font-weight: 700; font-variant-numeric: tabular-nums; }
.py-cal__brand   { font-size: 11px; color: var(--py-ink-subtle); }
.py-cal__excerpt { color: var(--py-ink-muted); line-height: 1.35; }
.py-cal__platform {
	font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
	color: var(--py-ink-subtle);
}

.py-cal__post--pending   { border-left-color: var(--py-warning); background: var(--py-warning-soft); }
/* The calendar collapses to three states: approved ("Scheduled, in PostYard's
   queue") and scheduled ("Scheduled, handed to a provider") both mean "going
   out at the shown time", so they share ONE green colour. The two classes stay
   distinct only so the drag rules can tell an approved (movable) card from a
   provider-held (fixed) one — see calendar.php. */
.py-cal__post--approved,
.py-cal__post--scheduled { border-left-color: var(--py-success); background: var(--py-success-soft); }
.py-cal__post--sent,
.py-cal__post--published { border-left-color: var(--py-border-strong); background: var(--py-surface-alt); }
.py-cal__post--failed    { border-left-color: var(--py-danger);  background: var(--py-danger-soft); }

/* Drag-and-drop rescheduling — a pending/approved card can be dragged onto any
   (non-past) day×hour cell to change its date and hour. Palette variables keep
   this correct in the dark theme with no extra overrides. Progressive
   enhancement; behaviour lives in frontend.js. */
.py-cal__post--draggable { cursor: grab; }
.py-cal__post--draggable.is-dragging {
	opacity: .55;
	cursor: grabbing;
	box-shadow: var(--py-shadow-lg);
}
.py-cal__cell.is-drop-target {
	background: var(--py-primary-soft);
	box-shadow: inset 0 0 0 2px var(--py-primary);
}

.py-cal-legend {
	display: flex; flex-wrap: wrap; gap: 8px 18px;
	margin-top: 16px; font-size: 12px; color: var(--py-ink-subtle);
}
.py-cal-legend__item { display: inline-flex; align-items: center; gap: 6px; }
.py-cal-legend__dot  { width: 10px; height: 10px; border-radius: 3px; border-left-width: 3px; border-left-style: solid; }

/* Posting-window day picker (account form → Posting windows) */
.py-window-days { display: flex; flex-wrap: wrap; gap: 6px; }
.py-window-day  { position: relative; }
.py-window-day input { position: absolute; opacity: 0; pointer-events: none; }
.py-window-day span {
	display: inline-block; min-width: 44px; text-align: center;
	padding: 6px 10px; font-size: 13px; font-weight: 600;
	border: 1px solid var(--py-border); border-radius: 999px;
	color: var(--py-ink-muted); background: var(--py-surface);
	cursor: pointer; transition: all .15s ease;
}
.py-window-day input:checked + span {
	background: var(--py-primary); border-color: var(--py-primary); color: #fff;
}
.py-window-day input:focus-visible + span { outline: 2px solid var(--py-primary); outline-offset: 2px; }

/* =========================================================================
   Post-type editor shell
   ---------------------------------------------------------------------
   The edit screen used to be one ~2500px scroll of nine equal-weight
   sections, with the delivery picker at the top and the API key it needs
   below the template designer. It is now five tab panels in a single form
   (so one Save still posts everything), with a sticky action bar.
   ========================================================================= */

/* Universal gate. Delivery mode hides whole sections; tab panels hide
   themselves. Both need to compose, so gating toggles this class rather
   than an inline display that would fight .is-active. */
.py-hide { display: none !important; }

.py-editor { display: block; }

.py-editor__head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
	margin-bottom: 18px;
}
.py-editor__title {
	margin: 0 0 4px;
	font-size: 22px;
	font-weight: 700;
	letter-spacing: -0.4px;
}
.py-editor__sub {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	margin: 0;
	font-size: 13px;
	color: var(--py-ink-subtle);
}
.py-editor__sub code {
	font-size: 12px;
	padding: 2px 6px;
	background: var(--py-surface-alt);
	border: 1px solid var(--py-border);
	border-radius: 5px;
}

/* ---- Step tabs ---- */
.py-wtabs {
	display: flex;
	gap: 2px;
	overflow-x: auto;
	margin-bottom: 22px;
	padding-bottom: 1px;
	border-bottom: 1px solid var(--py-border);
	scrollbar-width: thin;
}
.py-wtab {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 11px 15px;
	font-size: 13.5px;
	font-weight: 600;
	white-space: nowrap;
	color: var(--py-ink-subtle);
	background: transparent;
	border: none;
	border-bottom: 2px solid transparent;
	margin-bottom: -1px;
	cursor: pointer;
	transition: color .15s, border-color .15s;
}
.py-wtab:hover { color: var(--py-ink); }
.py-wtab.is-active { color: var(--py-primary); border-bottom-color: var(--py-primary); }
.py-wtab__num {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	font-size: 11px;
	font-weight: 700;
	border-radius: 50%;
	color: var(--py-ink-subtle);
	background: var(--py-surface-alt);
	border: 1px solid var(--py-border);
}
.py-wtab.is-active .py-wtab__num {
	color: #fff;
	background: var(--py-primary);
	border-color: var(--py-primary);
}

.py-wpanel { display: none; }
.py-wpanel.is-active { display: block; }

/* Leave room for the sticky bar so the last card is never trapped under it. */
.py-editor .py-wpanel { padding-bottom: 84px; }

/* ---- Cards: one idea per box ---- */
.py-panel {
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	padding: 20px;
	margin-bottom: 16px;
}
.py-panel--flush { padding: 20px 18px; }
.py-panel--status { background: var(--py-surface-alt); }

.py-panel__head { margin-bottom: 14px; }
.py-panel__head h3 {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 4px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: -0.2px;
}
.py-panel__head p {
	margin: 0;
	font-size: 13px;
	line-height: 1.55;
	color: var(--py-ink-subtle);
	max-width: 74ch;
}
.py-panel .py-field:last-child { margin-bottom: 0; }

/* ---- Delivery route cards ---- */
.py-routes {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 10px;
}
.py-route {
	position: relative;
	display: flex;
	align-items: flex-start;
	gap: 12px;
	padding: 14px;
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	cursor: pointer;
	transition: border-color .15s, box-shadow .15s, background .15s;
}
.py-route:hover { border-color: var(--py-border-strong); }
.py-route.is-selected {
	border-color: var(--py-primary);
	background: var(--py-primary-soft);
	box-shadow: 0 0 0 3px var(--py-primary-soft);
}
/* The radio itself stays in the accessibility tree and keyboard order —
   it's just visually replaced by the card + tick. */
.py-route input {
	position: absolute;
	width: 1px; height: 1px;
	opacity: 0;
	margin: 0;
	pointer-events: none;
}
.py-route:focus-within { outline: 2px solid var(--py-primary); outline-offset: 2px; }

.py-route__icon {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px; height: 34px;
	border-radius: 8px;
	color: var(--py-ink-muted);
	background: var(--py-surface-alt);
	border: 1px solid var(--py-border);
}
.py-route__icon svg { width: 18px; height: 18px; }
.py-route.is-selected .py-route__icon {
	color: #fff;
	background: var(--py-primary);
	border-color: var(--py-primary);
}

.py-route__text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.py-route__name { font-size: 13.5px; font-weight: 600; color: var(--py-ink); }
.py-route__desc { font-size: 12.5px; line-height: 1.5; color: var(--py-ink-subtle); }

.py-route__tick {
	flex: 0 0 auto;
	width: 16px; height: 16px;
	color: var(--py-primary);
	opacity: 0;
	transition: opacity .15s;
}
.py-route__tick svg { width: 16px; height: 16px; }
.py-route.is-selected .py-route__tick { opacity: 1; }

/* ---- Setup checklist ---- */
.py-checklist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.py-checklist__item {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	font-size: 13px;
	line-height: 1.5;
}
.py-checklist__item strong { font-weight: 600; color: var(--py-ink); }
.py-checklist__item em {
	display: block;
	font-style: normal;
	font-size: 12.5px;
	color: var(--py-ink-subtle);
}
.py-checklist__mark {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px; height: 18px;
	margin-top: 1px;
	font-size: 11px;
	font-weight: 700;
	border-radius: 50%;
}
.is-ok   > .py-checklist__mark { color: var(--py-success); background: var(--py-success-soft); }
.is-todo > .py-checklist__mark { color: var(--py-warning); background: var(--py-warning-soft); }

/* ---- Notes ---- */
.py-note {
	margin: 12px 0;
	padding: 10px 12px;
	font-size: 12.5px;
	line-height: 1.55;
	border-radius: var(--py-radius-sm);
	border: 1px solid transparent;
}
.py-note--info { color: var(--py-ink-muted); background: var(--py-surface-alt); border-color: var(--py-border); }
.py-note--warn { color: var(--py-warning);   background: var(--py-warning-soft); border-color: #fcd9a0; }

/* ---- Inline rows (an input beside its button) ---- */
.py-inline-row {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}
.py-inline-row > input:not([type="checkbox"]):not([type="color"]),
.py-inline-row > select,
.py-inline-row > textarea { flex: 1 1 220px; min-width: 0; }
.py-inline-row--tight > input,
.py-inline-row--tight > select { flex: 0 0 auto; }
.py-inline-row .py-btn { flex: 0 0 auto; }

.py-inline-status { font-size: 12.5px; color: var(--py-ink-subtle); }
.py-inline-status.is-ok  { color: var(--py-success); font-weight: 600; }
.py-inline-status.is-bad { color: var(--py-danger);  font-weight: 600; }

/* Brief green flash when a fetched ID is dropped into a field. */
input.is-flash {
	background: var(--py-success-soft);
	transition: background .4s ease;
}

/* ---- Fetch results (Buffer channels / SocialPilot accounts) ---- */
.py-fetch-result {
	margin: 10px 0 4px;
	padding: 12px;
	background: var(--py-surface-alt);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	overflow-x: auto;
}
.py-fetch-result__lead { margin: 0 0 10px; font-size: 12.5px; color: var(--py-ink-muted); }
.py-fetch-result__error { color: var(--py-danger); font-size: 13px; }
.py-fetch-result__detail {
	margin-top: 4px;
	font-size: 12px;
	color: var(--py-ink-muted);
	word-break: break-word;
}

/* ---- Progressive disclosure for the advanced bits ---- */
.py-help {
	margin: 12px 0 0;
	padding: 0;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	background: var(--py-surface-alt);
}
.py-help > summary {
	padding: 9px 12px;
	font-size: 12.5px;
	font-weight: 600;
	color: var(--py-ink-muted);
	cursor: pointer;
	list-style: none;
}
.py-help > summary::-webkit-details-marker { display: none; }
.py-help > summary::before { content: '▸ '; color: var(--py-ink-subtle); }
.py-help[open] > summary::before { content: '▾ '; }
.py-help[open] > summary { border-bottom: 1px solid var(--py-border); }
.py-help > *:not(summary) { margin: 12px; }
.py-help p {
	font-size: 12.5px;
	line-height: 1.6;
	color: var(--py-ink-subtle);
}
.py-help__lead { margin-top: 12px !important; }

/* ---- Repeatable rows (reshare rules, custom text fields) ---- */
.py-repeat { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.py-repeat__row {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 10px;
	margin-bottom: 10px;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	background: var(--py-surface-alt);
}
.py-repeat > .py-repeat__row { margin-bottom: 0; }
.py-repeat__row textarea { width: 100%; box-sizing: border-box; resize: vertical; }
.py-repeat__key {
	flex: 0 0 auto;
	font-family: 'SF Mono', Monaco, monospace;
	font-size: 11px;
	white-space: nowrap;
	color: var(--py-ink-subtle);
}

/* ---- Sticky save bar ---- */
.py-savebar {
	position: sticky;
	bottom: 0;
	z-index: 20;
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 -8px;
	padding: 12px 16px;
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius);
	box-shadow: var(--py-shadow-lg);
}
.py-savebar__left  { flex: 1; }
.py-savebar__right { display: flex; align-items: center; gap: 8px; }
.py-savebar__dirty {
	font-size: 12.5px;
	font-weight: 600;
	color: var(--py-warning);
}

/* A destructive action that shouldn't shout — used for Delete, which sits
   beside the primary Save. */
.py-btn--danger-text { color: var(--py-danger); }
.py-btn--danger-text:hover { color: #fff; background: var(--py-danger); border-color: var(--py-danger); }

/* `.py-btn--primary` carries `flex: 1` for the post-card action rows, where
   Approve is meant to fill the space beside Reject. Anywhere a primary button
   is simply one item in a flex row, that makes it stretch absurdly wide — so
   the post-type screens opt out. Left alone globally: the post card is what
   the rule was written for. */
.py-savebar .py-btn--primary,
.py-section__header .py-btn--primary,
.py-panel .py-btn--primary { flex: 0 0 auto; }

/* ---- Platform tiles ----
   .py-check already carries the tile chrome and its checked state; these only
   tighten the spacing and add the hover cue. */
.py-checkgroup--tiles { gap: 8px; }
.py-check--tile:hover { border-color: var(--py-border-strong); }

/* A right-aligned live value beside a control's label (slider readouts). */
.py-field__value { float: right; font-weight: 400; color: var(--py-ink-subtle); }

/* ---- Field rhythm inside the new card / inspector containers ----
   .py-field has never carried a bottom margin of its own (it relied on
   .py-form-grid's gap), so stacked single fields used to butt together. */
.py-panel > .py-field,
.py-panel > .py-help { margin-bottom: 16px; }
.py-panel > .py-field:last-child,
.py-panel > .py-help:last-child { margin-bottom: 0; }
.py-inspector .py-field { margin-bottom: 12px; }
.py-inspector .py-form-grid { margin-bottom: 12px; gap: 10px; }
.py-inspector .py-form-grid .py-field { margin-bottom: 0; }

/* A checkbox with an explanation under it: the box and its label sit on one
   line, the hint drops to its own. Deliberately two classes deep so it can't
   be undone by a later single-class `.py-field` rule the way the original
   `.py-field--checkbox` was. */
.py-field.py-field--checkbox {
	flex-direction: row;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
}
.py-field.py-field--checkbox > input[type="checkbox"] { flex: 0 0 auto; width: auto; margin: 0; }
.py-field.py-field--checkbox > .py-field__hint { flex: 1 0 100%; margin-left: 24px; }

/* =========================================================================
   Post-type listing extras
   ========================================================================= */

.py-listfilter {
	position: relative;
	max-width: 340px;
	margin-bottom: 16px;
}
.py-listfilter svg {
	position: absolute;
	left: 11px; top: 50%;
	width: 15px; height: 15px;
	transform: translateY(-50%);
	color: var(--py-ink-subtle);
	pointer-events: none;
}
.py-listfilter input {
	width: 100%;
	padding: 10px 14px 10px 34px;
	font-family: inherit;
	font-size: 14px;
	color: var(--py-ink);
	background: var(--py-surface);
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
}
.py-listfilter input:focus {
	outline: none;
	border-color: var(--py-primary);
	box-shadow: 0 0 0 3px var(--py-primary-soft);
}
.py-listfilter__empty {
	padding: 24px;
	text-align: center;
	color: var(--py-ink-subtle);
	font-size: 13px;
}

.py-brand-card__ident { min-width: 0; }

.py-brand-card__tags {
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
	margin: 10px 0 4px;
}
.py-tag {
	display: inline-flex;
	align-items: center;
	padding: 3px 9px;
	font-size: 11px;
	font-weight: 600;
	border-radius: 999px;
	border: 1px solid transparent;
	white-space: nowrap;
}
.py-tag--route { color: var(--py-ink-muted); background: var(--py-surface-alt); border-color: var(--py-border); }
.py-tag--ok    { color: var(--py-success);   background: var(--py-success-soft); border-color: #bbf7d0; }
.py-tag--todo  { color: var(--py-warning);   background: var(--py-warning-soft); border-color: #fcd9a0; cursor: help; }

.py-brand-card__actions {
	display: flex;
	align-items: center;
	gap: 6px;
	flex-wrap: wrap;
	margin-top: 4px;
}
.py-brand-card__inline-form { display: inline; margin: 0; }

@media (max-width: 720px) {
	.py-editor__head  { flex-direction: column; }
	.py-savebar       { flex-wrap: wrap; margin: 0; }
	.py-savebar__left { flex: 1 0 100%; }
	.py-routes        { grid-template-columns: 1fr; }
}

/* =========================================================================
   Per-post graphic editor (/post/{uid}/graphic)
   =========================================================================
   Deliberately tiny: the page reuses .py-tpl-editor / .py-inspector / .py-canvas
   wholesale, because that grid is already tuned for a square canvas beside a
   330px sticky inspector. Only these two status affordances are new.
   See docs/reference/per-post-graphic-editing.md. */
.py-graphic-count {
	float: right;
	font-variant-numeric: tabular-nums;
}
.py-graphic-count.is-near   { color: var(--py-warning, #b45309); font-weight: 600; }
.py-graphic-count.is-over   { color: var(--py-danger, #b91c1c);  font-weight: 700; }

.py-graphic-status {
	margin: 8px 0 0;
	font-size: 12px;
	line-height: 1.45;
	color: var(--py-ink-subtle);
}
.py-graphic-status.is-error { color: var(--py-danger, #b91c1c); }
.py-graphic-status.is-ok    { color: var(--py-success, #047857); }

/* The "hand-edited" marker on the post page. */
.py-pill--edited { border-style: dashed; }

/* "This post is a reshare" — accent-filled rather than neutral, so it reads as
   a fact about what the post IS, alongside the neutral status/format pills. */
.py-pill--reshare {
	background: var(--py-primary);
	color: #fff;
}

/* The reshare provenance panel on the post page: names the source, explains the
   reused graphic, and links the original. Same calm accent-rule treatment as
   the "PostYard can't make that change" panel — informative, not a warning. */
.py-detail__reshare {
	background: var(--py-surface-alt);
	border: 1px solid var(--py-border);
	border-left: 3px solid var(--py-primary);
	border-radius: var(--py-radius-sm);
	padding: 12px 14px;
	font-size: 13px;
	line-height: 1.55;
	color: var(--py-ink-muted);
}
.py-detail__reshare strong { color: var(--py-ink); }
.py-detail__reshare p { margin: 4px 0 0; }

/* -----------------------------------------------------------------------------
   Inline caption editing (post detail).

   The view state is the caption exactly as it rendered before this existed —
   .py-detail__caption is untouched — with an Edit button beside it; the form
   state replaces both. Only rendered when caption_edit_gate() says the post is
   still ours to change, so there is no disabled state to style.
   -------------------------------------------------------------------------- */
.py-caption-edit__view {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 12px;
}
.py-caption-edit__view .py-detail__caption { margin: 0; flex: 1 1 auto; }
.py-caption-edit-toggle {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 12px;
	padding: 5px 10px;
}

.py-caption-edit__label {
	display: block;
	font-size: 12px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .5px;
	color: var(--py-ink-subtle);
	margin-bottom: 6px;
}
.py-caption-edit__text {
	width: 100%;
	box-sizing: border-box;
	font: inherit;
	font-size: 14px;
	line-height: 1.7;
	color: var(--py-ink);
	padding: 10px 12px;
	border: 1px solid var(--py-border);
	border-radius: var(--py-radius-sm);
	background: var(--py-surface);
	resize: vertical;
}
.py-caption-edit__text:focus {
	outline: none;
	border-color: var(--py-primary);
}
.py-caption-edit__meta {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 8px;
	margin: 6px 0 10px;
	font-size: 12px;
	color: var(--py-ink-muted);
}
.py-caption-edit__count { font-variant-numeric: tabular-nums; }
/* The server refuses an over-length caption outright, so this is the warning
   that stops someone typing past the limit and losing the save. */
.py-caption-edit__count--over { color: var(--py-danger); font-weight: 600; }
